Module: CmAdmin::Models::DslMethod
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/cm_admin/models/dsl_method.rb
Instance Method Summary collapse
-
#action_group(name, icon_name: 'fa fa-list', icon_style: nil) ⇒ Object
Create a new group for actions.
-
#alert_box(header: nil, body: nil, type: nil, icon_name: nil, partial: nil, display_if: ->(_arg) { true }, html_attrs: {}) ⇒ Object
Adds a new alert to the current section.
-
#all_db_columns(options = {}) ⇒ Object
Get all columns for a model for index layout.
-
#bulk_action(name: nil, display_name: nil, display_if: ->(_) { true }, redirection_url: nil, icon_name: nil, verb: nil, display_type: nil, modal_configuration: {}, route_type: nil, partial: nil, icon_style: nil, execution_mode: :individual, success_message: ->(_arg) { nil }, error_message: ->(_arg) { nil }, alert_type: :banner, &block) ⇒ Object
Create a new bulk action for model.
-
#cm_edit(display_name: 'Edit', page_title: nil, page_description: nil, partial: nil, redirect_to: nil) ⇒ Object
Create a form for edit action.
-
#cm_index(display_name: nil, page_title: nil, page_description: nil, partial: nil, view_type: :table) ⇒ Object
Create a table for index page with pagination.
-
#cm_new(display_name: 'Add', page_title: nil, page_description: nil, partial: nil, redirect_to: nil, allow_create_action: -> { true }) ⇒ Object
Create a form for new action.
- #cm_section(section_name, display_if: nil, col_size: nil, html_attrs: nil, partial: nil, &block) ⇒ Object
-
#cm_show(display_name: nil, page_title: nil, page_description: nil, partial: nil) ⇒ Object
Create a view for show page.
-
#cm_show_section(section_name, display_if: nil, html_attrs: nil, partial: nil, &block) ⇒ Object
deprecated
Deprecated.
Use #cm_section instead of this method
-
#column(field_name, options = {}) ⇒ Object
Create a new column on index layout.
-
#custom_action(name: nil, page_title: nil, page_description: nil, display_name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, redirect_to: nil, modal_configuration: {}, url_params: {}, display_if: ->(_) { true }, route_type: nil, icon_name: 'fa fa-th-large', icon_style: nil, group_name: nil, success_message: ->(_) { nil }, error_message: ->(_, _) { nil }, alert_type: :flash, &block) ⇒ Object
Create a new custom action for model custom_action name: ‘change_password’, route_type: ‘member’, verb: ‘get’, icon_name: ‘fa-solid fa-key’, page_title: ‘Change Password’, path: ‘:id/change_password’, display_type: :form_modal do form do cm_section ‘Password Details’ do form_field :username form_field :age_group_id, input_type: :single_select, helper_method: :age_group_type_collection form_field :cultural_background_ids, input_type: :multi_select, helper_method: :cultural_background_type_collection form_field :language, input_type: :single_select, helper_method: :language_collection end end on_submit do @customer = ::Customer.find(params) @customer.update!(gender_id: params[:age_group_id]) @customer end end Note: The form block is mandatory for form modal and form page.
-
#eager_load_associations(associations = []) ⇒ Object
Configure Eager load associations for action This will help us avoid N+1 queries.
-
#filter(db_column_name, filter_type = nil, options = {}) ⇒ Object
Create a new filter for model.
-
#kanban_view(column_name, exclude: [], only: []) ⇒ Object
Set kanban view for current action.
-
#page_description(description) ⇒ Object
Set page description for current action.
-
#page_title(title) ⇒ Object
Set page title for current action.
-
#row(display_if: nil, html_attrs: nil, &block) ⇒ Object
Create a new row on page or form.
-
#scope_list(scopes = []) ⇒ Object
Set scopes for current action.
-
#sort_column(column = :created_at) ⇒ Object
@deprecated: use #sortable_columns instead of this method Set sort column for filters.
-
#sort_direction(direction = :desc) ⇒ Object
@deprecated: use #sortable_columns instead of this method Set sort direction for filters.
-
#sortable_columns(columns) ⇒ Object
Configure sortable columns for model verified_at is a JSONB column, so we need to specify the sort_datatype sortable_columns([‘id’, display_name: ‘ID’, default: true, default_direction: ‘desc’, ‘updated_at’, display_name: ‘Last Updated At’, ‘verified_at’, display_name: ‘Verified At’, sort_datatype: ‘TIMESTAMP’]).
-
#tab(tab_name, action_name, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, associated_model_name: nil, allow_create_action: -> { true }, &block) ⇒ Object
Create a new tab on show page.
Instance Method Details
#action_group(name, icon_name: 'fa fa-list', icon_style: nil) ⇒ Object
Create a new group for actions
295 296 297 298 299 |
# File 'lib/cm_admin/models/dsl_method.rb', line 295 def action_group(name, icon_name: 'fa fa-list', icon_style: nil) @current_group = { name:, icon_name:, icon_style: } yield @current_group = nil end |
#alert_box(header: nil, body: nil, type: nil, icon_name: nil, partial: nil, display_if: ->(_arg) { true }, html_attrs: {}) ⇒ Object
Alerts cannot be placed inside nested sections. If added within a nested section, the alert will appear on the wrapped cm_show_section.
Only the specified types (info, success, danger, warning) are supported. Any other type will default to a standard div.
Adds a new alert to the current section.
531 532 533 |
# File 'lib/cm_admin/models/dsl_method.rb', line 531 def alert_box(header: nil, body: nil, type: nil, icon_name: nil, partial: nil, display_if: ->(_arg) { true }, html_attrs: {}) @current_action.alerts << CmAdmin::Models::Alert.new(header:, body:, type:, icon_name:, partial:, display_if:, html_attrs:) end |
#all_db_columns(options = {}) ⇒ Object
Get all columns for a model for index layout.
274 275 276 277 278 279 280 281 282 283 |
# File 'lib/cm_admin/models/dsl_method.rb', line 274 def all_db_columns( = {}) field_names = instance_variable_get(:@ar_model)&.columns&.map { |x| x.name.to_sym } if .include?(:exclude) && field_names excluded_fields = ([] << [:exclude]).flatten.map(&:to_sym) field_names -= excluded_fields end field_names.each do |field_name| column field_name end end |
#bulk_action(name: nil, display_name: nil, display_if: ->(_) { true }, redirection_url: nil, icon_name: nil, verb: nil, display_type: nil, modal_configuration: {}, route_type: nil, partial: nil, icon_style: nil, execution_mode: :individual, success_message: ->(_arg) { nil }, error_message: ->(_arg) { nil }, alert_type: :banner, &block) ⇒ Object
Create a new bulk action for model
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
# File 'lib/cm_admin/models/dsl_method.rb', line 426 def bulk_action(name: nil, display_name: nil, display_if: ->(_) { true }, redirection_url: nil, icon_name: nil, verb: nil, display_type: nil, modal_configuration: {}, route_type: nil, partial: nil, icon_style: nil, execution_mode: :individual, success_message: ->(_arg) { nil }, error_message: ->(_arg) { nil }, alert_type: :banner, &block) bulk_action = CmAdmin::Models::BulkAction.new( name:, display_name:, display_if:, modal_configuration:, redirection_url:, icon_name:, action_type: :bulk_action, execution_mode:, verb:, display_type:, route_type:, partial:, icon_style:, success_message:, error_message:, alert_type:, &block ) if display_type == :form_modal @action = bulk_action @current_action = @action @current_action.verb = :post @available_actions << @action define_singleton_method(:on_submit) do |&code_block| @action.code_block = code_block end yield else @available_actions << bulk_action end end |
#cm_edit(display_name: 'Edit', page_title: nil, page_description: nil, partial: nil, redirect_to: nil) ⇒ Object
Create a form for edit action
Create a form field for form
@param form_field [String] the name of field
@param input_type [Symbol] the type of field, +:integer+, +:decimal+, +:string+, +:single_select+, +:multi_select+, +:date+, +:date_time+, +:text+, +:switch+, +:custom_single_select+, +:checkbox_group+, +:radio_button+, +:custom_string+, +:custom_date+, +:radio_button_group+
@param is_required [Boolean] the field is required or not, or can be set automatically based on model validation
@param collection [Array] the collection of field, use with single_select or multi_select
For understanding difference between switch and check_box, refer to https://blog.uxtweak.com/checkbox-vs-toggle-switch/
74 75 76 77 78 79 |
# File 'lib/cm_admin/models/dsl_method.rb', line 74 def cm_edit(display_name: 'Edit', page_title: nil, page_description: nil, partial: nil, redirect_to: nil) @current_action = CmAdmin::Models::Action.find_by(self, name: 'edit') page_title ||= "Edit #{ar_model.model_name.plural.titleize}" @current_action.set_values(display_name, page_title, page_description, partial, redirect_to) yield end |
#cm_index(display_name: nil, page_title: nil, page_description: nil, partial: nil, view_type: :table) ⇒ Object
Create a table for index page with pagination.

21 22 23 24 25 26 |
# File 'lib/cm_admin/models/dsl_method.rb', line 21 def cm_index(display_name: nil, page_title: nil, page_description: nil, partial: nil, view_type: :table) @current_action = CmAdmin::Models::Action.find_by(self, name: 'index') page_title ||= ar_model.model_name.plural.titleize @current_action.set_values(display_name, page_title, page_description, partial, view_type) yield end |
#cm_new(display_name: 'Add', page_title: nil, page_description: nil, partial: nil, redirect_to: nil, allow_create_action: -> { true }) ⇒ Object
Create a form for new action
Create a form field for form
@param form_field [String] the name of field
@param input_type [Symbol] the type of field, +:integer+, +:decimal+, +:string+, +:single_select+, +:multi_select+, +:date+, +:date_time+, +:text+, +:switch+, +:custom_single_select+, +:checkbox_group+, +:radio_button+, +:custom_string+, +:custom_date+, +:radio_button_group+
@param is_required [Boolean] the field is required or not, or can be set automatically based on model validation
@param collection [Array] the collection of field, use with single_select or multi_select
For understanding difference between switch and check_box, refer to https://blog.uxtweak.com/checkbox-vs-toggle-switch/
103 104 105 106 107 108 109 |
# File 'lib/cm_admin/models/dsl_method.rb', line 103 def cm_new(display_name: 'Add', page_title: nil, page_description: nil, partial: nil, redirect_to: nil, allow_create_action: -> { true }) @current_action = CmAdmin::Models::Action.find_by(self, name: 'new') page_title ||= "Add #{ar_model.model_name.plural.titleize}" @current_action.set_values(display_name, page_title, page_description, partial, redirect_to) @current_action.allow_create_action = allow_create_action yield end |
#cm_section(section_name, display_if: nil, col_size: nil, html_attrs: nil, partial: nil, &block) ⇒ Object
207 208 209 210 211 |
# File 'lib/cm_admin/models/dsl_method.rb', line 207 def cm_section(section_name, display_if: nil, col_size: nil, html_attrs: nil, partial: nil, &block) @available_fields[@current_action.name.to_sym] ||= [] @available_fields[@current_action.name.to_sym] << CmAdmin::Models::Section.new(section_name, @current_action, @model, display_if, html_attrs, col_size, partial, &block) end |
#cm_show(display_name: nil, page_title: nil, page_description: nil, partial: nil) ⇒ Object
Create a view for show page
46 47 48 49 50 51 |
# File 'lib/cm_admin/models/dsl_method.rb', line 46 def cm_show(display_name: nil, page_title: nil, page_description: nil, partial: nil) @current_action = CmAdmin::Models::Action.find_by(self, name: 'show') page_title ||= ar_model.model_name.plural.titleize @current_action.set_values(display_name, page_title, page_description, partial) yield end |
#cm_show_section(section_name, display_if: nil, html_attrs: nil, partial: nil, &block) ⇒ Object
Use #cm_section instead of this method
214 215 216 |
# File 'lib/cm_admin/models/dsl_method.rb', line 214 def cm_show_section(section_name, display_if: nil, html_attrs: nil, partial: nil, &block) cm_section(section_name, display_if:, html_attrs:, partial:, &block) end |
#column(field_name, options = {}) ⇒ Object
Create a new column on index layout.
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/cm_admin/models/dsl_method.rb', line 233 def column(field_name, = {}) return unless @current_action.instance_of?(CmAdmin::Models::Action) @available_fields[@current_action.name.to_sym] ||= [] if @available_fields[@current_action.name.to_sym].select(&:lockable).size.positive? && [:lockable] raise 'Only one column can be locked in a table.' end if @available_fields[@current_action.name.to_sym].select(&:kanban_image).size.positive? && [:kanban_image] raise 'Only one column can be kanban image in a card view.' end if @available_fields[@current_action.name.to_sym].select(&:kanban_footer).size >= 2 && [:kanban_footer] raise 'Only two columns can be kanban footer in a card view.' end duplicate_columns = @available_fields[@current_action.name.to_sym].filter { |x| x.field_name.to_sym == field_name } terminate = false if duplicate_columns.size.positive? duplicate_columns.each do |column| if [:field_type].to_s != 'association' terminate = true elsif [:field_type].to_s == 'association' && column.association_name.to_s == [:association_name].to_s terminate = true end end end return if terminate add_to_filter = [:add_to_filter].nil? || [:add_to_filter] generate_filter_for_columns(field_name, add_to_filter: add_to_filter) @available_fields[@current_action.name.to_sym] << CmAdmin::Models::Column.new(field_name, ) end |
#custom_action(name: nil, page_title: nil, page_description: nil, display_name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, redirect_to: nil, modal_configuration: {}, url_params: {}, display_if: ->(_) { true }, route_type: nil, icon_name: 'fa fa-th-large', icon_style: nil, group_name: nil, success_message: ->(_) { nil }, error_message: ->(_, _) { nil }, alert_type: :flash, &block) ⇒ Object
Create a new custom action for model custom_action name: ‘change_password’, route_type: ‘member’, verb: ‘get’, icon_name: ‘fa-solid fa-key’, page_title: ‘Change Password’, path: ‘:id/change_password’, display_type: :form_modal do
form do
cm_section 'Password Details' do
form_field :username
form_field :age_group_id, input_type: :single_select, helper_method: :age_group_type_collection
form_field :cultural_background_ids, input_type: :multi_select, helper_method: :cultural_background_type_collection
form_field :language, input_type: :single_select, helper_method: :language_collection
end
end
on_submit do
@customer = ::Customer.find(params[:id])
@customer.update!(gender_id: params[:customer][:age_group_id])
@customer
end
end Note: The form block is mandatory for form modal and form page. Params fields will always be under the parent class, for example: params[:age_group_id]
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/cm_admin/models/dsl_method.rb', line 353 def custom_action(name: nil, page_title: nil, page_description: nil, display_name: nil, verb: nil, layout: nil, layout_type: nil, partial: nil, path: nil, display_type: nil, redirect_to: nil, modal_configuration: {}, url_params: {}, display_if: ->(_) { true }, route_type: nil, icon_name: 'fa fa-th-large', icon_style: nil, group_name: nil, success_message: ->(_) { nil }, error_message: ->(_, _) { nil }, alert_type: :flash, &block) @action = CmAdmin::Models::CustomAction.new( page_title:, page_description:, name:, display_name:, verb:, layout:, layout_type:, partial:, path:, parent: current_action.name, display_type:, display_if:, redirect_to:, action_type: :custom, route_type:, icon_name:, icon_style:, modal_configuration:, model_name: self.name, url_params:, group_name:, alert_type:, success_message:, error_message:, &block ) if @current_group @action.group_name = @current_group[:name] @action.group_icon_name = @current_group[:icon_name] @action.group_icon_style = @current_group[:icon_style] end if %i[form_page form_modal].include?(display_type) @current_action = @action @available_actions << @action define_singleton_method(:on_submit) do |&code_block| if display_type == :form_modal @action.code_block = code_block else @action.verb = :get generate_update_action(name, path, verb, redirect_to, route_type, , , &code_block) end end yield else @available_actions << @action end end |
#eager_load_associations(associations = []) ⇒ Object
Configure Eager load associations for action This will help us avoid N+1 queries
594 595 596 |
# File 'lib/cm_admin/models/dsl_method.rb', line 594 def eager_load_associations(associations = []) @current_action.eager_load_associations = associations if @current_action end |
#filter(db_column_name, filter_type = nil, options = {}) ⇒ Object
Create a new filter for model
469 470 471 472 |
# File 'lib/cm_admin/models/dsl_method.rb', line 469 def filter(db_column_name, filter_type = nil, = {}) filter_type = default_filter_type(db_column_name, filter_type) @filters << CmAdmin::Models::Filter.new(db_column_name:, filter_type:, options:) end |
#kanban_view(column_name, exclude: [], only: []) ⇒ Object
Set kanban view for current action
131 132 133 134 135 136 137 |
# File 'lib/cm_admin/models/dsl_method.rb', line 131 def kanban_view(column_name, exclude: [], only: []) return unless @current_action @current_action.kanban_attr[:column_name] = column_name @current_action.kanban_attr[:exclude] = exclude @current_action.kanban_attr[:only] = only end |
#page_description(description) ⇒ Object
Set page description for current action
121 122 123 124 125 |
# File 'lib/cm_admin/models/dsl_method.rb', line 121 def page_description(description) return unless @current_action @current_action.page_description = description end |
#page_title(title) ⇒ Object
Set page title for current action
113 114 115 116 117 |
# File 'lib/cm_admin/models/dsl_method.rb', line 113 def page_title(title) return unless @current_action @current_action.page_title = title end |
#row(display_if: nil, html_attrs: nil, &block) ⇒ Object
Create a new row on page or form.
192 193 194 195 |
# File 'lib/cm_admin/models/dsl_method.rb', line 192 def row(display_if: nil, html_attrs: nil, &block) @available_fields[@current_action.name.to_sym] ||= [] @available_fields[@current_action.name.to_sym] << CmAdmin::Models::Row.new(@current_action, @model, display_if, html_attrs, &block) end |
#scope_list(scopes = []) ⇒ Object
Set scopes for current action
141 142 143 144 145 |
# File 'lib/cm_admin/models/dsl_method.rb', line 141 def scope_list(scopes = []) return unless @current_action @current_action.scopes = scopes end |
#sort_column(column = :created_at) ⇒ Object
@deprecated: use #sortable_columns instead of this method Set sort column for filters
493 494 495 |
# File 'lib/cm_admin/models/dsl_method.rb', line 493 def sort_column(column = :created_at) @current_action.sort_column = column.to_sym if @current_action end |
#sort_direction(direction = :desc) ⇒ Object
@deprecated: use #sortable_columns instead of this method Set sort direction for filters
479 480 481 482 483 484 485 486 |
# File 'lib/cm_admin/models/dsl_method.rb', line 479 def sort_direction(direction = :desc) unless CmAdmin::Models::Action::VALID_SORT_DIRECTION.include?(direction.to_sym.downcase) raise ArgumentError, "Select a valid sort direction like #{CmAdmin::Models::Action::VALID_SORT_DIRECTION.join(' or ')} instead of #{direction}" end @current_action.sort_direction = direction.to_sym if @current_action end |
#sortable_columns(columns) ⇒ Object
default sort direction will be ascending
Configure sortable columns for model verified_at is a JSONB column, so we need to specify the sort_datatype
sortable_columns([{column: 'id', display_name: 'ID', default: true, default_direction: 'desc'},
{column: 'updated_at', display_name: 'Last Updated At'},
{column: 'verified_at', display_name: 'Verified At', sort_datatype: 'TIMESTAMP'}])
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/cm_admin/models/dsl_method.rb', line 567 def sortable_columns(columns) @sort_columns = columns.map do |column| column[:display_if] ||= ->(_arg) { true } column end default_column = @sort_columns.filter do |column| column.key?(:default) || column.key?(:default_direction) end raise ArgumentError, 'only one column can be default' if default_column.size > 1 if default_column.blank? @default_sort_column = nil @default_sort_direction = 'asc' return end default_column = default_column.first @default_sort_column = default_column[:column] @default_sort_direction = default_column[:default_direction] if default_column[:default_direction].present? end |
#tab(tab_name, action_name, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, associated_model_name: nil, allow_create_action: -> { true }, &block) ⇒ Object
Create a new tab on show page.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/cm_admin/models/dsl_method.rb', line 164 def tab(tab_name, action_name, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, associated_model_name: nil, allow_create_action: -> { true }, &block) action_name = action_name.to_s.gsub(' ', '').underscore if action_name.to_s == '' @current_action = CmAdmin::Models::Action.find_by(self, name: 'show') @available_tabs << CmAdmin::Models::Tab.new(tab_name, '', display_if, show_count, &block) else action = CmAdmin::Models::Action.new(name: action_name.to_s, verb: :get, path: ":id/#{action_name}", layout_type:, layout:, partial:, child_records: associated_model, action_type: :tab, display_type: :page, model_name: name, view_type:, associated_model_name:, allow_create_action:) @available_actions << action @current_action = action @available_tabs << CmAdmin::Models::Tab.new(tab_name, action_name, display_if, show_count, &block) end yield if block end |