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: nil, 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 }, &block) ⇒ Object
Create a new bulk action for model.
-
#cm_edit(page_title: nil, page_description: nil, partial: nil, redirect_to: nil) ⇒ Object
Create a form for edit action.
-
#cm_index(page_title: nil, page_description: nil, partial: nil, view_type: :table) ⇒ Object
Create a table for index page with pagination.
-
#cm_new(page_title: nil, page_description: nil, partial: nil, redirect_to: nil) ⇒ 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(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 }, &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, &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
286 287 288 289 290 |
# File 'lib/cm_admin/models/dsl_method.rb', line 286 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: nil, 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.
514 515 516 |
# File 'lib/cm_admin/models/dsl_method.rb', line 514 def alert_box(header: nil, body: nil, type: nil, icon_name: nil, partial: nil, display_if: nil, html_attrs: {}) @section_fields << 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.
265 266 267 268 269 270 271 272 273 274 |
# File 'lib/cm_admin/models/dsl_method.rb', line 265 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 }, &block) ⇒ Object
Create a new bulk action for model
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/cm_admin/models/dsl_method.rb', line 415 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 }, &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:, &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(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/
71 72 73 74 75 76 |
# File 'lib/cm_admin/models/dsl_method.rb', line 71 def cm_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(page_title, page_description, partial, redirect_to) yield end |
#cm_index(page_title: nil, page_description: nil, partial: nil, view_type: :table) ⇒ Object
Create a table for index page with pagination.
20 21 22 23 24 25 |
# File 'lib/cm_admin/models/dsl_method.rb', line 20 def cm_index(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(page_title, page_description, partial, view_type) yield end |
#cm_new(page_title: nil, page_description: nil, partial: nil, redirect_to: nil) ⇒ 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/
98 99 100 101 102 103 |
# File 'lib/cm_admin/models/dsl_method.rb', line 98 def cm_new(page_title: nil, page_description: nil, partial: nil, redirect_to: nil) @current_action = CmAdmin::Models::Action.find_by(self, name: 'new') page_title ||= "Add #{ar_model.model_name.plural.titleize}" @current_action.set_values(page_title, page_description, partial, redirect_to) yield end |
#cm_section(section_name, display_if: nil, col_size: nil, html_attrs: nil, partial: nil, &block) ⇒ Object
200 201 202 203 204 |
# File 'lib/cm_admin/models/dsl_method.rb', line 200 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(page_title: nil, page_description: nil, partial: nil) ⇒ Object
Create a view for show page
44 45 46 47 48 49 |
# File 'lib/cm_admin/models/dsl_method.rb', line 44 def cm_show(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(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
207 208 209 |
# File 'lib/cm_admin/models/dsl_method.rb', line 207 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.
225 226 227 228 229 230 231 232 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 |
# File 'lib/cm_admin/models/dsl_method.rb', line 225 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 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 }, &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]
343 344 345 346 347 348 349 350 351 352 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 |
# File 'lib/cm_admin/models/dsl_method.rb', line 343 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 }, &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:, 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
556 557 558 |
# File 'lib/cm_admin/models/dsl_method.rb', line 556 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
452 453 454 455 |
# File 'lib/cm_admin/models/dsl_method.rb', line 452 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
125 126 127 128 129 130 131 |
# File 'lib/cm_admin/models/dsl_method.rb', line 125 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
115 116 117 118 119 |
# File 'lib/cm_admin/models/dsl_method.rb', line 115 def page_description(description) return unless @current_action @current_action.page_description = description end |
#page_title(title) ⇒ Object
Set page title for current action
107 108 109 110 111 |
# File 'lib/cm_admin/models/dsl_method.rb', line 107 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.
185 186 187 188 |
# File 'lib/cm_admin/models/dsl_method.rb', line 185 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
135 136 137 138 139 |
# File 'lib/cm_admin/models/dsl_method.rb', line 135 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
476 477 478 |
# File 'lib/cm_admin/models/dsl_method.rb', line 476 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
462 463 464 465 466 467 468 469 |
# File 'lib/cm_admin/models/dsl_method.rb', line 462 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'}])
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/cm_admin/models/dsl_method.rb', line 530 def sortable_columns(columns) @sort_columns = columns default_column = 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, &block) ⇒ Object
Create a new tab on show page.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/cm_admin/models/dsl_method.rb', line 158 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, &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:) @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 |