Module: CmAdmin::Models::DslMethod
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/cm_admin/models/dsl_method.rb
Instance Method Summary collapse
-
#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, execution_mode: :individual, &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', group_name: 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, 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, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, &block) ⇒ Object
Create a new tab on show page.
Instance Method Details
#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.
439 440 441 |
# File 'lib/cm_admin/models/dsl_method.rb', line 439 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.
252 253 254 255 256 257 258 259 260 261 |
# File 'lib/cm_admin/models/dsl_method.rb', line 252 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, execution_mode: :individual, &block) ⇒ Object
Create a new bulk action for model
352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/cm_admin/models/dsl_method.rb', line 352 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, execution_mode: :individual, &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:, &block ) @available_actions << bulk_action 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
197 198 199 200 201 |
# File 'lib/cm_admin/models/dsl_method.rb', line 197 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
204 205 206 |
# File 'lib/cm_admin/models/dsl_method.rb', line 204 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.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/cm_admin/models/dsl_method.rb', line 222 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 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 @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', group_name: 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]
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/cm_admin/models/dsl_method.rb', line 313 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', group_name: 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:, modal_configuration:, model_name: self.name, url_params:, group_name:, &block ) if %i[form_page form_modal].include?(display_type) handle_form_action(name, path, redirect_to, route_type, page_title, page_description, &block) 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
481 482 483 |
# File 'lib/cm_admin/models/dsl_method.rb', line 481 def eager_load_associations(associations = []) @current_action.eager_load_associations = associations if @current_action end |
#filter(db_column_name, filter_type, options = {}) ⇒ Object
Create a new filter for model
378 379 380 |
# File 'lib/cm_admin/models/dsl_method.rb', line 378 def filter(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.
182 183 184 185 |
# File 'lib/cm_admin/models/dsl_method.rb', line 182 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
401 402 403 |
# File 'lib/cm_admin/models/dsl_method.rb', line 401 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
387 388 389 390 391 392 393 394 |
# File 'lib/cm_admin/models/dsl_method.rb', line 387 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'}])
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/cm_admin/models/dsl_method.rb', line 455 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, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, &block) ⇒ Object
Create a new tab on show page.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/cm_admin/models/dsl_method.rb', line 157 def tab(tab_name, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil, display_if: nil, show_count: true, view_type: nil, &block) if custom_action.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: custom_action.to_s, verb: :get, path: ":id/#{custom_action}", layout_type:, layout:, partial:, child_records: associated_model, action_type: :custom, display_type: :page, model_name: name, view_type:) @available_actions << action @current_action = action @available_tabs << CmAdmin::Models::Tab.new(tab_name, custom_action, display_if, show_count, &block) end yield if block end |