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 }, &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
287 288 289 290 291 |
# File 'lib/cm_admin/models/dsl_method.rb', line 287 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.
515 516 517 |
# File 'lib/cm_admin/models/dsl_method.rb', line 515 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.
266 267 268 269 270 271 272 273 274 275 |
# File 'lib/cm_admin/models/dsl_method.rb', line 266 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
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/cm_admin/models/dsl_method.rb', line 416 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 260 |
# 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 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 }, &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]
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 383 |
# File 'lib/cm_admin/models/dsl_method.rb', line 344 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
557 558 559 |
# File 'lib/cm_admin/models/dsl_method.rb', line 557 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
453 454 455 456 |
# File 'lib/cm_admin/models/dsl_method.rb', line 453 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
477 478 479 |
# File 'lib/cm_admin/models/dsl_method.rb', line 477 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
463 464 465 466 467 468 469 470 |
# File 'lib/cm_admin/models/dsl_method.rb', line 463 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'}])
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/cm_admin/models/dsl_method.rb', line 531 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 |