avo 2.31.0 → 2.32.0

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/app/assets/stylesheets/avo.base.css +0 -1
  4. data/app/assets/svgs/map-empty-state.svg +35 -0
  5. data/app/assets/svgs/map-view-type.svg +3 -0
  6. data/app/components/avo/fields/area_field/edit_component.html.erb +7 -0
  7. data/app/components/avo/fields/area_field/edit_component.rb +4 -0
  8. data/app/components/avo/fields/area_field/show_component.html.erb +8 -0
  9. data/app/components/avo/fields/area_field/show_component.rb +4 -0
  10. data/app/components/avo/fields/country_field/edit_component.html.erb +2 -1
  11. data/app/components/avo/fields/location_field/show_component.html.erb +1 -1
  12. data/app/components/avo/fields/number_field/edit_component.html.erb +2 -1
  13. data/app/components/avo/fields/password_field/edit_component.html.erb +2 -1
  14. data/app/components/avo/fields/select_field/edit_component.html.erb +2 -1
  15. data/app/components/avo/fields/text_field/edit_component.html.erb +2 -1
  16. data/app/components/avo/index/resource_map_component.html.erb +16 -0
  17. data/app/components/avo/index/resource_map_component.rb +109 -0
  18. data/app/components/avo/views/resource_index_component.html.erb +9 -0
  19. data/app/controllers/avo/application_controller.rb +4 -0
  20. data/app/views/avo/partials/_view_toggle_button.html.erb +5 -0
  21. data/db/factories.rb +1 -0
  22. data/lib/avo/app.rb +18 -3
  23. data/lib/avo/base_action.rb +4 -4
  24. data/lib/avo/base_resource.rb +2 -0
  25. data/lib/avo/concerns/fetches_things.rb +1 -3
  26. data/lib/avo/fields/area_field.rb +39 -0
  27. data/lib/avo/fields/base_field.rb +2 -0
  28. data/lib/avo/fields/location_field.rb +0 -1
  29. data/lib/avo/licensing/h_q.rb +1 -0
  30. data/lib/avo/version.rb +1 -1
  31. data/public/avo-assets/avo.base.css +24 -0
  32. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2d89325380615d00eeac9d1c507409b602452f320e96ce8818830b580cb5ffd
4
- data.tar.gz: 787b185e5f37182a75dec5935ea5cd0a2d1cd1986981b79ff6393bfc021e649d
3
+ metadata.gz: 7bde773a8062f76d29ce0655fd0948bf963f1a0627b02d3d9df706225049fab6
4
+ data.tar.gz: 6503ea6bde6130648c2f2613e097ee9cc8db3e58d07702fea4d47a94b62a5118
5
5
  SHA512:
6
- metadata.gz: 02eba26931bf6ea8300df3fc44006ad2390ddb3dd0ca6b474b438bd29953a5203e97f6b301297bc119572a8bef80341b62fcd7cc6c4ecf1dd7b065441ed168ff
7
- data.tar.gz: fde51151f29f9c2c06d00cbdb0e16be8d594eb72c20669ad54944adb5d4f105098bf5f84b9a3878b3324837a3ea4086f067dc5030151161409f599699b06ae55
6
+ metadata.gz: c17065eb96f4b82a8f0d33f50627e635462e737c3fae582ab371c10a7976594df137fa8db3bb77252fcbc5d4c873ec4eb3db24c8ddedd201c6d830574be5687d
7
+ data.tar.gz: 762e69b4a753622e1a6ad3eef2038e27acf05b36356bbe31a1cb7798ba1491f65306fb867d4eea41f0ffe8870c959c66df8f5a55768620119d7158ef56a6e05a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (2.31.0)
4
+ avo (2.32.0)
5
5
  actionview (>= 6.0)
6
6
  active_link_to
7
7
  activerecord (>= 6.0)
@@ -275,7 +275,7 @@ GEM
275
275
  nokogiri (1.14.3-x86_64-linux)
276
276
  racc (~> 1.4)
277
277
  orm_adapter (0.5.0)
278
- pagy (6.0.3)
278
+ pagy (6.0.4)
279
279
  parallel (1.22.1)
280
280
  parser (3.2.0.0)
281
281
  ast (~> 2.4.1)
@@ -71,7 +71,6 @@ body {
71
71
  @apply opacity-0 translate-y-1;
72
72
  }
73
73
 
74
-
75
74
  .turbo-progress-bar {
76
75
  @apply bg-primary-400;
77
76
  }
@@ -0,0 +1,35 @@
1
+ <svg width="248" height="287" viewBox="0 0 248 287" fill="none" xmlns="http://www.w3.org/2000/svg" data-target="grid-empty-state-svg">
2
+ <path d="M124 270.227C192.483 270.227 248 214.71 248 146.227C248 77.7433 192.483 22.2266 124 22.2266C55.5167 22.2266 0 77.7433 0 146.227C0 214.71 55.5167 270.227 124 270.227Z" fill="rgb(var(--color-primary-100))"/>
3
+ <g filter="rgb(var(--color-primary-100))">
4
+ <path d="M195.093 93.3198H52.9068C48.3412 93.3198 44.6401 97.0209 44.6401 101.586V275.186C44.6401 279.752 48.3412 283.453 52.9068 283.453H195.093C199.659 283.453 203.36 279.752 203.36 275.186V101.586C203.36 97.0209 199.659 93.3198 195.093 93.3198Z" fill="white"/>
5
+ </g>
6
+ <path d="M107.467 118.12H64.48C61.7407 118.12 59.52 120.34 59.52 123.08C59.52 125.819 61.7407 128.04 64.48 128.04H107.467C110.206 128.04 112.427 125.819 112.427 123.08C112.427 120.34 110.206 118.12 107.467 118.12Z" fill="rgb(var(--color-primary-100))"/>
7
+ <path d="M137.227 139.613H64.48C61.7407 139.613 59.52 141.834 59.52 144.573C59.52 147.312 61.7407 149.533 64.48 149.533H137.227C139.966 149.533 142.187 147.312 142.187 144.573C142.187 141.834 139.966 139.613 137.227 139.613Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
8
+ <path d="M107.467 162.76H64.48C61.7407 162.76 59.52 164.981 59.52 167.72C59.52 170.459 61.7407 172.68 64.48 172.68H107.467C110.206 172.68 112.427 170.459 112.427 167.72C112.427 164.981 110.206 162.76 107.467 162.76Z" fill="rgb(var(--color-primary-100))"/>
9
+ <path d="M137.227 184.253H64.48C61.7407 184.253 59.52 186.474 59.52 189.213C59.52 191.953 61.7407 194.173 64.48 194.173H137.227C139.966 194.173 142.187 191.953 142.187 189.213C142.187 186.474 139.966 184.253 137.227 184.253Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
10
+ <path d="M107.467 207.4H64.48C61.7407 207.4 59.52 209.621 59.52 212.36C59.52 215.099 61.7407 217.32 64.48 217.32H107.467C110.206 217.32 112.427 215.099 112.427 212.36C112.427 209.621 110.206 207.4 107.467 207.4Z" fill="rgb(var(--color-primary-100))"/>
11
+ <path d="M137.227 228.893H64.48C61.7407 228.893 59.52 231.114 59.52 233.853C59.52 236.592 61.7407 238.813 64.48 238.813H137.227C139.966 238.813 142.187 236.592 142.187 233.853C142.187 231.114 139.966 228.893 137.227 228.893Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
12
+ <g filter="url(#filter1_d_577_1090)">
13
+ <path d="M195.093 9H52.9068C48.3412 9 44.6401 12.7011 44.6401 17.2667V66.8667C44.6401 71.4322 48.3412 75.1333 52.9068 75.1333H195.093C199.659 75.1333 203.36 71.4322 203.36 66.8667V17.2667C203.36 12.7011 199.659 9 195.093 9Z" fill="rgb(var(--color-primary-500))"/>
14
+ </g>
15
+ <path d="M107.467 27.1865H64.48C61.7407 27.1865 59.52 29.4072 59.52 32.1465C59.52 34.8859 61.7407 37.1065 64.48 37.1065H107.467C110.206 37.1065 112.427 34.8859 112.427 32.1465C112.427 29.4072 110.206 27.1865 107.467 27.1865Z" fill="rgb(var(--color-primary-100))"/>
16
+ <path d="M137.227 48.6799H64.48C61.7407 48.6799 59.52 50.9006 59.52 53.6399C59.52 56.3793 61.7407 58.5999 64.48 58.5999H137.227C139.966 58.5999 142.187 56.3793 142.187 53.6399C142.187 50.9006 139.966 48.6799 137.227 48.6799Z" fill="white"/>
17
+ <defs>
18
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
19
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
20
+ <feOffset dy="-3"/>
21
+ <feGaussianBlur stdDeviation="3"/>
22
+ <feColorMatrix type="matrix" values="0 0 0 0 0.788235 0 0 0 0 0.803922 0 0 0 0 0.85098 0 0 0 0.349 0"/>
23
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_577_1090"/>
24
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_577_1090" result="shape"/>
25
+ <filter id="filter1_d_577_1090" x="38.6401" y="0" width="170.72" height="78.1333" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
26
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
27
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
28
+ <feOffset dy="-3"/>
29
+ <feGaussianBlur stdDeviation="3"/>
30
+ <feColorMatrix type="matrix" values="0 0 0 0 0.788235 0 0 0 0 0.803922 0 0 0 0 0.85098 0 0 0 0.349 0"/>
31
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_577_1090"/>
32
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_577_1090" result="shape"/>
33
+ </filter>
34
+ </defs>
35
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
2
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 6.75V15m6-6v8.25m.503 3.498l4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 00-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0z"/>
3
+ </svg>
@@ -0,0 +1,7 @@
1
+ <%= field_wrapper **field_wrapper_args do %>
2
+ <%= @form.text_field @field.id,
3
+ class: classes("w-full"),
4
+ value: field.value.to_s,
5
+ placeholder: @field.placeholder,
6
+ disabled: disabled? %>
7
+ <% end %>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::AreaField::EditComponent < Avo::Fields::EditComponent
4
+ end
@@ -0,0 +1,8 @@
1
+ <%= field_wrapper **field_wrapper_args do %>
2
+ <% if field.value.present? %>
3
+ <%= area_map field.map_data, **field.mapkick_options %>
4
+ <% else %>
5
+
6
+ <% end %>
7
+ <% end %>
8
+
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::AreaField::ShowComponent < Avo::Fields::ShowComponent
4
+ end
@@ -10,6 +10,7 @@
10
10
  data: @field.get_html(:data, view: view, element: :input),
11
11
  disabled: disabled?,
12
12
  style: @field.get_html(:style, view: view, element: :input),
13
- placeholder: @field.include_blank.present? ? nil : @field.placeholder
13
+ placeholder: @field.include_blank.present? ? nil : @field.placeholder,
14
+ autocomplete: @field.autocomplete
14
15
  %>
15
16
  <% end %>
@@ -1,6 +1,6 @@
1
1
  <%= field_wrapper **field_wrapper_args do %>
2
2
  <% if field.value_present? %>
3
- <%= js_map [{latitude: field.value[0], longitude: field.value[1]}] %>
3
+ <%= js_map [{latitude: field.value[0], longitude: field.value[1]}], id: "location-map" %>
4
4
  <% else %>
5
5
 
6
6
  <% end %>
@@ -7,6 +7,7 @@
7
7
  min: @field.min,
8
8
  placeholder: @field.placeholder,
9
9
  step: @field.step,
10
- style: @field.get_html(:style, view: view, element: :input)
10
+ style: @field.get_html(:style, view: view, element: :input),
11
+ autocomplete: @field.autocomplete
11
12
  %>
12
13
  <% end %>
@@ -4,6 +4,7 @@
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
5
  disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
- style: @field.get_html(:style, view: view, element: :input)
7
+ style: @field.get_html(:style, view: view, element: :input),
8
+ autocomplete: @field.autocomplete
8
9
  %>
9
10
  <% end %>
@@ -10,6 +10,7 @@
10
10
  disabled: disabled?,
11
11
  style: @field.get_html(:style, view: view, element: :input),
12
12
  value: @field.model.present? ? @field.model[@field.id] : @field.value,
13
- placeholder: @field.include_blank.present? ? nil : @field.placeholder
13
+ placeholder: @field.include_blank.present? ? nil : @field.placeholder,
14
+ autocomplete: @field.autocomplete
14
15
  %>
15
16
  <% end %>
@@ -6,6 +6,7 @@
6
6
  placeholder: @field.placeholder,
7
7
  style: @field.get_html(:style, view: view, element: :input),
8
8
  # value: @field.value,
9
- multiple: multiple
9
+ multiple: multiple,
10
+ autocomplete: @field.autocomplete
10
11
  %>
11
12
  <% end %>
@@ -0,0 +1,16 @@
1
+ <% if @resources.present? %>
2
+ <div class="map-view-container grid <%= grid_layout_classes %>">
3
+ <div class="map-component min-h-full <%= map_component_order_class %>">
4
+ <%= js_map(resource_location_markers, **resource_mapkick_options) %>
5
+ </div>
6
+ <% if render_table? %>
7
+ <div class="overflow-auto<%= table_component_order_class %>">
8
+ <%= render(Avo::Index::ResourceTableComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model, parent_resource: @parent_resource, pagy: @pagy, query: @query)) %>
9
+ </div>
10
+ <% end %>
11
+ </div>
12
+ <% else %>
13
+ <div class="bg-white rounded shadow-panel">
14
+ <%= helpers.empty_state by_association: params[:related_name].present?, view_type: :map %>
15
+ </div>
16
+ <% end %>
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avo
4
+ module Index
5
+ # Render a map view for a list of resources, where each resource is
6
+ # expected to have an attribute/attribute set representing its location.
7
+ class ResourceMapComponent < ViewComponent::Base
8
+ attr_reader :resources
9
+
10
+ def initialize(resources: nil, resource: nil, reflection: nil, parent_model: nil, parent_resource: nil, pagy: nil, query: nil)
11
+ super
12
+ @resources = resources
13
+ @resource = resource
14
+ @reflection = reflection
15
+ @parent_model = parent_model
16
+ @parent_resource = parent_resource
17
+ @pagy = pagy
18
+ @query = query
19
+ end
20
+
21
+ def grid_layout_classes
22
+ return unless render_table?
23
+
24
+ if table_positioned_horizontally
25
+ "grid-flow-row sm:grid-flow-col grid-rows-1 auto-cols-fr"
26
+ elsif table_positioned_vertically
27
+ "grid-flow-row grid-cols-1"
28
+ end
29
+ end
30
+
31
+ def table_positioned_horizontally
32
+ %i[left right].include?(map_view_table_layout)
33
+ end
34
+
35
+ def table_positioned_vertically
36
+ %i[bottom top].include?(map_view_table_layout)
37
+ end
38
+
39
+ def map_component_order_class
40
+ if render_table? && table_positioned_at_the_start
41
+ "order-last"
42
+ else
43
+ "order-first"
44
+ end
45
+ end
46
+
47
+ def table_component_order_class
48
+ if table_positioned_at_the_start
49
+ "order-first"
50
+ else
51
+ "order-last"
52
+ end
53
+ end
54
+
55
+ def table_positioned_at_the_start
56
+ %i[left top].include?(map_view_table_layout)
57
+ end
58
+
59
+ def map_view_table_layout
60
+ map_options.dig(:table, :layout)
61
+ end
62
+
63
+ def resource_location_markers
64
+ # If we have no proc and no default location method, don't try to create markers
65
+ return [] unless resource_mappable?
66
+
67
+ resources
68
+ .map do |resource|
69
+ Avo::Hosts::ResourceRecordHost.new(block: marker_proc, resource: resource, record: resource.record).handle
70
+ end
71
+ .compact
72
+ .filter do |coordinates|
73
+ coordinates[:latitude].present? && coordinates[:longitude].present?
74
+ end
75
+ end
76
+
77
+ def resource_mapkick_options
78
+ map_options[:mapkick_options] || {}
79
+ end
80
+
81
+ def render_table?
82
+ map_options.dig(:table, :visible)
83
+ end
84
+
85
+ private
86
+
87
+ def default_record_marker_proc
88
+ lambda {
89
+ {
90
+ latitude: record.coordinates.first,
91
+ longitude: record.coordinates.last
92
+ }
93
+ }
94
+ end
95
+
96
+ def map_options
97
+ @resource.map_view || {}
98
+ end
99
+
100
+ def marker_proc
101
+ map_options[:record_marker] || default_record_marker_proc
102
+ end
103
+
104
+ def resource_mappable?
105
+ map_options[:record_marker].present? || @resources.first.record.respond_to?(:coordinates)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -46,6 +46,15 @@
46
46
  </div>
47
47
  <% end %>
48
48
  </div>
49
+ <% if view_type.to_sym == :map %>
50
+ <% if @resources.present? %>
51
+ <div>
52
+ <%= render(Avo::Index::ResourceMapComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model, parent_resource: @parent_resource, pagy: @pagy, query: @query)) %>
53
+ </div>
54
+ <% else %>
55
+ <%= helpers.empty_state by_association: params[:related_name].present?, view_type: view_type, add_background: true %>
56
+ <% end %>
57
+ <% end %>
49
58
  <% if view_type.to_sym == :table %>
50
59
  <% if @resources.present? %>
51
60
  <div class="w-full relative flex-1 flex mt-0">
@@ -155,6 +155,10 @@ module Avo
155
155
  def set_model_to_fill
156
156
  @model_to_fill = @resource.model_class.new if @view == :create
157
157
  @model_to_fill = @model if @view == :update
158
+
159
+ # If resource.model is nil, most likely the user is creating a new record.
160
+ # In that case, to access resource.model in visible and readonly blocks we hydrate the resource with a new model.
161
+ @resource.hydrate(model: @model_to_fill) if @resource.model.nil?
158
162
  end
159
163
 
160
164
  def fill_model
@@ -15,6 +15,11 @@
15
15
  new_view_type: 'list',
16
16
  new_icon: 'queue-list',
17
17
  },
18
+ map: {
19
+ new_view_type: 'map',
20
+ new_icon: 'map-view-type',
21
+ translation_key: 'avo.map_view',
22
+ },
18
23
  }
19
24
  %>
20
25
  <div class="flex">
data/db/factories.rb CHANGED
@@ -112,6 +112,7 @@ FactoryBot.define do
112
112
  description { Faker::Address.community }
113
113
  status { ["open", "closed"].sample }
114
114
  tiny_description { Faker::Address.community }
115
+ city_center_area { [[[10.0, 11.2], [10.5, 11.9], [10.8, 12.0], [10.0, 11.2]]].to_json }
115
116
  end
116
117
 
117
118
  factory :product do
data/lib/avo/app.rb CHANGED
@@ -31,10 +31,25 @@ module Avo
31
31
  def boot
32
32
  init_fields
33
33
 
34
- if Rails.cache.instance_of?(ActiveSupport::Cache::NullStore)
35
- self.cache_store ||= ActiveSupport::Cache::MemoryStore.new
34
+ self.cache_store = get_cache_store
35
+ end
36
+
37
+ # When not in production we'll just use the MemoryStore which is good enough.
38
+ # Wehn running in production we'll try to use memcached or redis if available.
39
+ # If not, we'll use the FileStore.
40
+ # We decided against the MemoryStore in production because it will not be shared between multiple processes (when using Puma).
41
+ def get_cache_store
42
+ if Rails.env.production?
43
+ case Rails.cache.class
44
+ when ActiveSupport::Cache::MemCacheStore, ActiveSupport::Cache::RedisCacheStore
45
+ Rails.cache
46
+ else
47
+ ActiveSupport::Cache::FileStore.new
48
+ end
49
+ elsif Rails.env.test?
50
+ Rails.cache
36
51
  else
37
- self.cache_store = Rails.cache
52
+ ActiveSupport::Cache::MemoryStore.new
38
53
  end
39
54
  end
40
55
 
@@ -58,10 +58,10 @@ module Avo
58
58
  end
59
59
 
60
60
  def initialize(model: nil, resource: nil, user: nil, view: nil, arguments: {})
61
- self.class.model = model if model.present?
62
- self.class.resource = resource if resource.present?
63
- self.class.user = user if user.present?
64
- self.class.view = view if view.present?
61
+ self.class.model = model
62
+ self.class.resource = resource
63
+ self.class.user = user
64
+ self.class.view = view
65
65
  @arguments = arguments
66
66
 
67
67
  self.class.message ||= I18n.t("avo.are_you_sure_you_want_to_run_this_option")
@@ -55,6 +55,7 @@ module Avo
55
55
  class_attribute :keep_filters_panel_open, default: false
56
56
  class_attribute :extra_params
57
57
  class_attribute :link_to_child_resource, default: false
58
+ class_attribute :map_view
58
59
 
59
60
  class << self
60
61
  delegate :t, to: ::I18n
@@ -295,6 +296,7 @@ module Avo
295
296
  view_types = [:table]
296
297
 
297
298
  view_types << :grid if get_grid_fields.present?
299
+ view_types << :map if map_view.present?
298
300
 
299
301
  view_types
300
302
  end
@@ -24,9 +24,7 @@ module Avo
24
24
 
25
25
  # Filters out the resources that are missing the model_class
26
26
  def valid_resources
27
- resources.select do |resource|
28
- resource.model_class.present?
29
- end
27
+ resources.select { |resource| resource.model_class.present? }.sort_by(&:name)
30
28
  end
31
29
 
32
30
  # Returns the Avo resource by camelized name
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avo
4
+ module Fields
5
+ class AreaField < BaseField
6
+ attr_reader :mapkick_options
7
+ attr_reader :datapoint_options
8
+
9
+ def initialize(id, **args, &block)
10
+ hide_on :index
11
+
12
+ super(id, **args, &block)
13
+
14
+ @geometry = args[:geometry].presence || :polygon # Accepts: `:polygon` or `:multi_polygon`
15
+ @mapkick_options = args[:mapkick_options].presence || {}
16
+ @datapoint_options = args[:datapoint_options].presence || {}
17
+ end
18
+
19
+ def map_data
20
+ data_source = {
21
+ geometry: {
22
+ type: @geometry.to_s.classify,
23
+ coordinates: value
24
+ }
25
+ }
26
+
27
+ [data_source.merge(datapoint_options)]
28
+ end
29
+
30
+ def coordinates
31
+ value.present? ? JSON.parse(value) : []
32
+ end
33
+
34
+ def geometry
35
+ @geometry.to_s.classify
36
+ end
37
+ end
38
+ end
39
+ end
@@ -30,6 +30,7 @@ module Avo
30
30
  attr_reader :nullable
31
31
  attr_reader :null_values
32
32
  attr_reader :format_using
33
+ attr_reader :autocomplete
33
34
  attr_reader :help
34
35
  attr_reader :default
35
36
  attr_reader :visible
@@ -70,6 +71,7 @@ module Avo
70
71
  @null_values = args[:null_values] || [nil, ""]
71
72
  @format_using = args[:format_using] || nil
72
73
  @placeholder = args[:placeholder]
74
+ @autocomplete = args[:autocomplete] || nil
73
75
  @help = args[:help] || nil
74
76
  @default = args[:default] || nil
75
77
  @visible = args[:visible]
@@ -7,7 +7,6 @@ module Avo
7
7
 
8
8
  def initialize(id, **args, &block)
9
9
  hide_on :index
10
-
11
10
  super(id, **args, &block)
12
11
 
13
12
  @stored_as = args[:stored_as].present? ? args[:stored_as] : nil # You can pass it an array of db columns [:latitude, :longitude]
@@ -106,6 +106,7 @@ module Avo
106
106
  **other_metadata(:filters),
107
107
  main_menu_present: Avo.configuration.main_menu.present?,
108
108
  profile_menu_present: Avo.configuration.profile_menu.present?,
109
+ cache_store: Avo::App.cache_store&.class&.to_s,
109
110
  **config_metadata
110
111
  }
111
112
  rescue
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.31.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.32.0" unless const_defined?(:VERSION)
3
3
  end
@@ -6374,6 +6374,14 @@ trix-toolbar .trix-button-group:not(:first-child){
6374
6374
  z-index:30
6375
6375
  }
6376
6376
 
6377
+ .order-last{
6378
+ order:9999
6379
+ }
6380
+
6381
+ .order-first{
6382
+ order:-9999
6383
+ }
6384
+
6377
6385
  .col-span-1{
6378
6386
  grid-column:span 1 / span 1
6379
6387
  }
@@ -6922,6 +6930,14 @@ trix-toolbar .trix-button-group:not(:first-child){
6922
6930
  appearance:none
6923
6931
  }
6924
6932
 
6933
+ .auto-cols-fr{
6934
+ grid-auto-columns:minmax(0, 1fr)
6935
+ }
6936
+
6937
+ .grid-flow-row{
6938
+ grid-auto-flow:row
6939
+ }
6940
+
6925
6941
  .grid-cols-1{
6926
6942
  grid-template-columns:repeat(1, minmax(0, 1fr))
6927
6943
  }
@@ -6930,6 +6946,10 @@ trix-toolbar .trix-button-group:not(:first-child){
6930
6946
  grid-template-columns:repeat(6, minmax(0, 1fr))
6931
6947
  }
6932
6948
 
6949
+ .grid-rows-1{
6950
+ grid-template-rows:repeat(1, minmax(0, 1fr))
6951
+ }
6952
+
6933
6953
  .flex-row{
6934
6954
  flex-direction:row
6935
6955
  }
@@ -9502,6 +9522,10 @@ trix-editor {
9502
9522
  max-width:42rem
9503
9523
  }
9504
9524
 
9525
+ .sm\:grid-flow-col{
9526
+ grid-auto-flow:column
9527
+ }
9528
+
9505
9529
  .sm\:grid-cols-3{
9506
9530
  grid-template-columns:repeat(3, minmax(0, 1fr))
9507
9531
  }
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: 2.31.0
4
+ version: 2.32.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Marin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-04-25 00:00:00.000000000 Z
12
+ date: 2023-05-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -1292,6 +1292,8 @@ files:
1292
1292
  - app/assets/svgs/information-circle.svg
1293
1293
  - app/assets/svgs/library.svg
1294
1294
  - app/assets/svgs/logout.svg
1295
+ - app/assets/svgs/map-empty-state.svg
1296
+ - app/assets/svgs/map-view-type.svg
1295
1297
  - app/assets/svgs/menu-back.svg
1296
1298
  - app/assets/svgs/menu.svg
1297
1299
  - app/assets/svgs/photograph.svg
@@ -1337,6 +1339,10 @@ files:
1337
1339
  - app/components/avo/empty_state_component.rb
1338
1340
  - app/components/avo/field_wrapper_component.html.erb
1339
1341
  - app/components/avo/field_wrapper_component.rb
1342
+ - app/components/avo/fields/area_field/edit_component.html.erb
1343
+ - app/components/avo/fields/area_field/edit_component.rb
1344
+ - app/components/avo/fields/area_field/show_component.html.erb
1345
+ - app/components/avo/fields/area_field/show_component.rb
1340
1346
  - app/components/avo/fields/badge_field/index_component.html.erb
1341
1347
  - app/components/avo/fields/badge_field/index_component.rb
1342
1348
  - app/components/avo/fields/badge_field/show_component.html.erb
@@ -1536,6 +1542,8 @@ files:
1536
1542
  - app/components/avo/index/resource_controls_component.rb
1537
1543
  - app/components/avo/index/resource_grid_component.html.erb
1538
1544
  - app/components/avo/index/resource_grid_component.rb
1545
+ - app/components/avo/index/resource_map_component.html.erb
1546
+ - app/components/avo/index/resource_map_component.rb
1539
1547
  - app/components/avo/index/resource_table_component.html.erb
1540
1548
  - app/components/avo/index/resource_table_component.rb
1541
1549
  - app/components/avo/index/table_row_component.html.erb
@@ -1741,6 +1749,7 @@ files:
1741
1749
  - lib/avo/dsl/field_parser.rb
1742
1750
  - lib/avo/dynamic_router.rb
1743
1751
  - lib/avo/engine.rb
1752
+ - lib/avo/fields/area_field.rb
1744
1753
  - lib/avo/fields/badge_field.rb
1745
1754
  - lib/avo/fields/base_field.rb
1746
1755
  - lib/avo/fields/belongs_to_field.rb