Module: Avo::Concerns::HasItems

Extended by:
ActiveSupport::Concern
Included in:
BaseAction, BaseResource, Resources::Items::ItemGroup, Resources::Items::Row, Resources::Items::Sidebar, Resources::Items::Tab, Resources::Items::TabGroup
Defined in:
lib/avo/concerns/has_items.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#items_holderObject



51
52
53
# File 'lib/avo/concerns/has_items.rb', line 51

def items_holder
  @items_holder || Avo::Resources::Items::Holder.new
end

Instance Method Details

#fields(**args) ⇒ Object



63
64
65
# File 'lib/avo/concerns/has_items.rb', line 63

def fields(**args)
  self.class.fields(**args)
end

#get_field(id) ⇒ Object



173
174
175
176
177
# File 'lib/avo/concerns/has_items.rb', line 173

def get_field(id)
  get_field_definitions.find do |f|
    f.id == id.to_sym
  end
end

#get_field_definitions(only_root: false) ⇒ Object



109
110
111
112
113
# File 'lib/avo/concerns/has_items.rb', line 109

def get_field_definitions(only_root: false)
  only_fields(only_root: only_root).map do |field|
    field.hydrate(resource: self, user: user, view: view)
  end
end

#get_fields(panel: nil, reflection: nil, only_root: false) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/avo/concerns/has_items.rb', line 121

def get_fields(panel: nil, reflection: nil, only_root: false)
  fields = get_field_definitions(only_root: only_root)
    .select do |field|
      # Get the fields for this view
      field.visible_in_view?(view: view)
    end
    .select do |field|
      field.visible?
    end
    .select do |field|
      is_valid = true

      # Strip out the reflection field in index queries with a parent association.
      if reflection.present?
        # regular non-polymorphic association
        # we're matching the reflection inverse_of foriegn key with the field's foreign_key
        if field.is_a?(Avo::Fields::BelongsToField)
          if field.respond_to?(:foreign_key) &&
              reflection.inverse_of.present? &&
              reflection.inverse_of.respond_to?(:foreign_key) &&
              reflection.inverse_of.foreign_key == field.foreign_key
            is_valid = false
          end

          # polymorphic association
          if field.respond_to?(:foreign_key) &&
              field.is_polymorphic? &&
              reflection.respond_to?(:polymorphic?) &&
              reflection.inverse_of.respond_to?(:foreign_key) &&
              reflection.inverse_of.foreign_key == field.reflection.foreign_key
            is_valid = false
          end
        end
      end

      is_valid
    end

  if panel.present?
    fields = fields.select do |field|
      field.panel_name == panel
    end
  end

  # hydrate_fields fields
  fields.each do |field|
    field.hydrate(record: @record, view: @view, resource: self)
  end

  fields
end

#get_itemsObject

Separates the fields that are in a panel and those that are just hanging out. Take the ones that aren’t placed into a panel and add them to the “default” panel. This is to keep compatibility with the versions before 2.10 when you didn’t have the ability to add fields to panels.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/avo/concerns/has_items.rb', line 200

def get_items
  panelless_items = []
  panelfull_items = []

  visible_items
    .each do |item|
      if item.is_field?
        if item.has_own_panel?
          panelfull_items << item
        else
          panelless_items << item
        end
      else
        panelfull_items << item
      end
    end

  # Make sure all tabs panelfull_items are setted as inside tabs
  panelfull_items.grep(Avo::Resources::Items::TabGroup).each do |tab_group|
    tab_group.items.grep(Avo::Resources::Items::Tab).each do |tab|
      tab.items.grep(Avo::Resources::Items::Panel).each do |panel|
        set_target_to_top panel.items.grep(Avo::Fields::BelongsToField)

        panel.items.grep(Avo::Resources::Items::Row).each do |row|
          set_target_to_top row.items.grep(Avo::Fields::BelongsToField)
        end
      end
    end
  end

  # Add all the panelles fields to a new panel
  main_panel_holder = Avo::Resources::Items::Holder.new
  main_panel_holder.items = panelless_items

  # Add that panel to the main panel
  main_panel = Avo::Resources::Items::MainPanel.new
  main_panel.items_holder = main_panel_holder

  # Return all the items but this time with all the panelless ones inside the main panel
  [main_panel, *panelfull_items]
end

#get_preview_fieldsObject



115
116
117
118
119
# File 'lib/avo/concerns/has_items.rb', line 115

def get_preview_fields
  get_field_definitions.select do |field|
    field.visible_in_view?(view: :preview)
  end
end

#invalid_fieldsObject

def items

items_holder.items

end



59
60
61
# File 'lib/avo/concerns/has_items.rb', line 59

def invalid_fields
  items_holder.invalid_fields
end

#is_empty?Boolean

Returns:

  • (Boolean)


294
295
296
# File 'lib/avo/concerns/has_items.rb', line 294

def is_empty?
  visible_items.blank?
end

#itemsObject



242
243
244
245
246
247
248
# File 'lib/avo/concerns/has_items.rb', line 242

def items
  if items_holder.present?
    items_holder.items
  else
    []
  end
end

#only_fields(only_root: false) ⇒ Object

Dives deep into panels and tabs to fetch all the fields for a resource.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/avo/concerns/has_items.rb', line 72

def only_fields(only_root: false)
  fields = []

  items.each do |item|
    next if item.nil?

    unless only_root
      # Dive into panels to fetch their fields
      if item.is_panel?
        fields << extract_fields_from_items(item)
      end

      # Dive into tabs to fetch their fields
      if item.is_tab_group?
        item.items.map do |tab|
          fields << extract_fields_from_items(tab)
        end
      end

      # Dive into sidebar to fetch their fields
      if item.is_sidebar?
        fields << extract_fields_from_items(item)
      end
    end

    if item.is_field?
      fields << item
    end

    if item.is_row?
      fields << extract_fields_from_items(tab)
    end
  end

  fields.flatten
end

#tab_groupsObject



67
68
69
# File 'lib/avo/concerns/has_items.rb', line 67

def tab_groups
  self.class.tab_groups
end

#toolsObject



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/avo/concerns/has_items.rb', line 179

def tools
  return [] if self.class.tools.blank?

  items
    .select do |item|
      next if item.nil?

      item.is_tool?
    end
    .map do |tool|
      tool.hydrate view: view
      tool
    end
    .select do |item|
      item.visible_in_view?(view: view)
    end
end

#visible_itemsObject



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/avo/concerns/has_items.rb', line 250

def visible_items
  items
    .map do |item|
      if view.present?
        res = self.class.ancestors.include?(Avo::BaseResource) ? self : resource
        item.hydrate(view: view, resource: res)
      end

      item
    end
    .select do |item|
      item.visible?
    end
    .select do |item|
      if item.respond_to?(:visible_in_view?)
        item.visible_in_view? view: view
      else
        true
      end
    end
    .select do |item|
      # On location field we can have field coordinates and setters with different names like latitude and longitude
      if !item.is_a?(Avo::Fields::LocationField) && !item.is_heading? && view.in?(%w[edit update new create])
        if item.respond_to?(:id)
          item.resource.record.respond_to?("#{item.id}=")
        else
          true
        end
      else
        true
      end
    end
    .select do |item|
      # Check if the user is authorized to view it.
      # This is usually used for has_* fields
      if item.respond_to? :authorized?
        item.authorized?
      else
        true
      end
    end
    .compact
end