Class: Admin::Base::Resource

Inherits:
Object
  • Object
show all
Extended by:
AdminSuite::Deprecation
Defined in:
lib/admin/base/resource.rb

Overview

Base class for admin resource definitions

Provides a declarative DSL for defining admin resources with:

  • Index configuration (columns, filters, search, sort, stats)
  • Form configuration (fields with various types)
  • Actions (single and bulk)
  • Show page sections
  • Export capabilities

Examples:

class Admin::Resources::CompanyResource < Admin::Base::Resource
  model Company
  portal :ops
  section :content

  index do
    searchable :name, :website
    sortable :name, :created_at, default: :name

    columns do
      column :name
      column :job_listings, -> (c) { c.job_listings.count }
    end

    filters do
      filter :search, type: :text
      filter :status, type: :select, options: %w[active inactive]
    end
  end

  form do
    field :name, required: true
    field :website, type: :url
    field :is_active, type: :toggle
  end
end

Defined Under Namespace

Classes: ActionDefinition, ActionsConfig, ColumnDefinition, ColumnsBuilder, FieldDefinition, FilterDefinition, FiltersBuilder, FormConfig, IndexConfig, RowDefinition, SectionDefinition, ShowConfig, ShowSectionDefinition, StatDefinition, StatsBuilder

Constant Summary collapse

EXPORTABLE_DEPRECATION_MESSAGE_FORMAT =
"AdminSuite: %<resource>s calls `exportable`, which is a deprecated " \
"no-op and will be removed in 0.5.0. It never actually implemented " \
"export in any released version — safe to delete the call."
SectionEnd =
Class.new
RowEnd =
Class.new

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from AdminSuite::Deprecation

reset_deprecation_notices!, warn_once, warn_once_sink

Class Attribute Details

.actions_configObject (readonly)

Actions configuration



63
64
65
# File 'lib/admin/base/resource.rb', line 63

def actions_config
  @actions_config
end

.form_configObject (readonly)

Form configuration



57
58
59
# File 'lib/admin/base/resource.rb', line 57

def form_config
  @form_config
end

.index_configObject (readonly)

Index configuration



54
55
56
# File 'lib/admin/base/resource.rb', line 54

def index_config
  @index_config
end

.model_classObject (readonly)

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def model_class
  @model_class
end

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def nav_icon
  @nav_icon
end

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def nav_label
  @nav_label
end

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def nav_order
  @nav_order
end

.portal_nameObject (readonly)

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def portal_name
  @portal_name
end

.section_nameObject (readonly)

Model configuration



51
52
53
# File 'lib/admin/base/resource.rb', line 51

def section_name
  @section_name
end

.show_configObject (readonly)

Show configuration



60
61
62
# File 'lib/admin/base/resource.rb', line 60

def show_config
  @show_config
end

Class Method Details

.actions { ... } ⇒ void

This method returns an undefined value.

Configures actions

Yields:

  • Block for actions configuration



159
160
161
162
# File 'lib/admin/base/resource.rb', line 159

def actions(&block)
  @actions_config = ActionsConfig.new
  @actions_config.instance_eval(&block) if block_given?
end

.exportable(*_formats) ⇒ void

This method returns an undefined value.

Deprecated no-op, removed in 0.5.0.

exportable was write-only in every prior release -- it never had a reader and never drove any export behavior -- but hosts still call it from resource-definition bodies (gleania: 30 files; trust_growth: 1). A real removal would raise NoMethodError at definition-load time, and in production DefinitionLoader logs and swallows that, so the resource just silently vanishes from the admin. Kept as a no-op instead, so those files keep loading.

Deliberately does not restore @export_formats or any reader -- only the harmless no-op comes back.

Parameters:

  • _formats (Array<Symbol>)

    ignored



190
191
192
193
194
195
196
197
# File 'lib/admin/base/resource.rb', line 190

def exportable(*_formats)
  # `warn_once`, `warn_once_sink` and `reset_deprecation_notices!`
  # come from `AdminSuite::Deprecation`, extended above. Keyed on the
  # resource class itself, so each resource warns independently (and
  # only once) rather than one call anywhere silencing every other
  # resource's first call.
  warn_once(name, format(EXPORTABLE_DEPRECATION_MESSAGE_FORMAT, resource: name))
end

.form { ... } ⇒ void

This method returns an undefined value.

Configures the form (new/edit)

Yields:

  • Block for form configuration



141
142
143
144
# File 'lib/admin/base/resource.rb', line 141

def form(&block)
  @form_config = FormConfig.new
  @form_config.instance_eval(&block) if block_given?
end

.human_nameString

Returns the human-readable name

Returns:

  • (String)


216
217
218
# File 'lib/admin/base/resource.rb', line 216

def human_name
  model_class&.model_name&.human || resource_name.humanize
end

.human_name_pluralString

Returns the human-readable plural name

Returns:

  • (String)


223
224
225
# File 'lib/admin/base/resource.rb', line 223

def human_name_plural
  model_class&.model_name&.human(count: 2) || resource_name.pluralize.humanize
end

.icon(name = nil) ⇒ String, ...

Convenience setter/getter for nav icon.

Parameters:

  • name (String, Symbol, nil) (defaults to: nil)

Returns:

  • (String, Symbol, nil)


105
106
107
108
# File 'lib/admin/base/resource.rb', line 105

def icon(name = nil)
  @nav_icon = name if name.present?
  @nav_icon
end

.index { ... } ⇒ void

This method returns an undefined value.

Configures the index view

Yields:

  • Block for index configuration



132
133
134
135
# File 'lib/admin/base/resource.rb', line 132

def index(&block)
  @index_config = IndexConfig.new
  @index_config.instance_eval(&block) if block_given?
end

.inherited(subclass) ⇒ Object

Called when a subclass is created



242
243
244
245
246
247
248
249
250
251
252
# File 'lib/admin/base/resource.rb', line 242

def inherited(subclass)
  super
  return if subclass.name&.include?("Base")

  existing_idx = registered_resources.index { |r| r.name == subclass.name }
  if existing_idx
    registered_resources[existing_idx] = subclass
  else
    registered_resources << subclass
  end
end

.label(name = nil) ⇒ String?

Convenience setter/getter for nav label.

Parameters:

  • name (String, nil) (defaults to: nil)

Returns:

  • (String, nil)


114
115
116
117
# File 'lib/admin/base/resource.rb', line 114

def label(name = nil)
  @nav_label = name if name.present?
  @nav_label
end

.model(klass) ⇒ void

This method returns an undefined value.

Sets the model class for this resource

Parameters:

  • klass (Class)

    The ActiveRecord model class



69
70
71
# File 'lib/admin/base/resource.rb', line 69

def model(klass)
  @model_class = klass
end

This method returns an undefined value.

Navigation metadata for this resource.

Parameters:

  • label (String, nil) (defaults to: nil)

    override label used in nav

  • icon (String, Symbol, nil) (defaults to: nil)

    lucide icon name (or raw svg string)

  • order (Integer, nil) (defaults to: nil)

    sort order within section



95
96
97
98
99
# File 'lib/admin/base/resource.rb', line 95

def nav(label: nil, icon: nil, order: nil)
  @nav_label = label if label.present?
  @nav_icon = icon if icon.present?
  @nav_order = order unless order.nil?
end

.order(value = nil) ⇒ Integer?

Convenience setter/getter for nav order.

Parameters:

  • value (Integer, nil) (defaults to: nil)

Returns:

  • (Integer, nil)


123
124
125
126
# File 'lib/admin/base/resource.rb', line 123

def order(value = nil)
  @nav_order = value unless value.nil?
  @nav_order
end

.portal(name) ⇒ void

This method returns an undefined value.

Sets the portal this resource belongs to

Parameters:

  • name (Symbol)

    Portal name (:ops or :ai)



77
78
79
# File 'lib/admin/base/resource.rb', line 77

def portal(name)
  @portal_name = name
end

.read_only(value = true) ⇒ Object

Declares whether the generic resource routes may mutate records. Read-only resources retain index/show access while the controller rejects direct requests to every built-in mutation endpoint.



167
168
169
# File 'lib/admin/base/resource.rb', line 167

def read_only(value = true)
  @read_only = value
end

.read_only?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/admin/base/resource.rb', line 171

def read_only?
  @read_only == true
end

.registered_resourcesArray<Class>

Returns all registered resources

Returns:

  • (Array<Class>)


230
231
232
# File 'lib/admin/base/resource.rb', line 230

def registered_resources
  @registered_resources ||= []
end

.reset_registry!void

This method returns an undefined value.

Clears the registry (useful for development reloads).



237
238
239
# File 'lib/admin/base/resource.rb', line 237

def reset_registry!
  @registered_resources = []
end

.resource_nameString

Returns the resource name derived from class name

Returns:

  • (String)


202
203
204
# File 'lib/admin/base/resource.rb', line 202

def resource_name
  name.demodulize.sub(/Resource$/, "").underscore
end

.resource_name_pluralString

Returns the plural resource name

Returns:

  • (String)


209
210
211
# File 'lib/admin/base/resource.rb', line 209

def resource_name_plural
  resource_name.pluralize
end

.resources_for_portal(portal) ⇒ Array<Class>

Returns resources for a specific portal

Parameters:

  • portal (Symbol)

    Portal name

Returns:

  • (Array<Class>)


258
259
260
# File 'lib/admin/base/resource.rb', line 258

def resources_for_portal(portal)
  registered_resources.select { |r| r.portal_name == portal }
end

.resources_for_section(portal, section) ⇒ Array<Class>

Returns resources for a specific section

Parameters:

  • portal (Symbol)

    Portal name

  • section (Symbol)

    Section name

Returns:

  • (Array<Class>)


267
268
269
# File 'lib/admin/base/resource.rb', line 267

def resources_for_section(portal, section)
  registered_resources.select { |r| r.portal_name == portal && r.section_name == section }
end

.section(name) ⇒ void

This method returns an undefined value.

Sets the section within the portal

Parameters:

  • name (Symbol)

    Section name



85
86
87
# File 'lib/admin/base/resource.rb', line 85

def section(name)
  @section_name = name
end

.show { ... } ⇒ void

This method returns an undefined value.

Configures the show view

Yields:

  • Block for show configuration



150
151
152
153
# File 'lib/admin/base/resource.rb', line 150

def show(&block)
  @show_config = ShowConfig.new
  @show_config.instance_eval(&block) if block_given?
end