# frozen_string_literal: true # # Helper to create a modal dialog for a given model # module ModelModalHelper # # Render the relationship for the model, using caching to speed things up a bit # # This helper should be used on the related objects in the table, to cut down on the database queries when rendering # the table. # def related_modal_tag(model, relation, options = {}) related_model = fetch_related_model(model, relation) return if related_model.blank? dynamic_related_modal(related_model, related_model_edit_path(model, relation, related_model, options), options) end # # Only show the trigger with the edit path, let the rest be generated later # def dynamic_related_modal(related_model, edit_path, _options = {}) model_name = related_model.class.to_s.underscore datum = { view_url: edit_path.gsub('/edit', '') } anchor_id = "#{model_name}-#{related_model.id}" title = related_model.respond_to?(:short_name) ? related_model.short_name : related_model.name content_tag(:div) do concat(content_tag(:a, href: "##{anchor_id}", class: 'modal-trigger') do concat(content_tag(:span, title)) end) concat(content_tag(:div, id: anchor_id, class: 'modal', data: datum) do concat(content_tag(:div, class: 'modal-content') do concat(content_tag(:h2, class: 'center') do concat(content_tag(:span, related_model.name)) end) concat(content_tag(:div, class: 'center-align') do concat(content_tag(:div, class: 'progress red lighten-4') do tag(:div, class: 'indeterminate red') end) end) end) concat(model_modal_footer(related_model, edit_path)) end) end end def related_model_edit_path(model, relation, related_model, options = {}) if options[:parent].present? parent_model = fetch_related_model(model, options[:parent]) send("edit_#{options[:parent]}_#{relation}_path", parent_model, related_model) else send("edit_#{relation}_path", related_model) end end def fetch_related_model(model, relation) # First get the relationship from cache related_id = model.send("#{relation}_id") key = "model_modal::#{relation}::#{related_id}" Rails.cache.fetch(key, expires_in: 6.hours) { model.send(relation) } end # # Render a modal tag for the given model object # def model_modal_tag(model, edit_path, options = {}) model_modal_action(model, options) + model_modal(model, edit_path, options) end def model_modal_action(model, _options = {}) content_tag(:a, class: 'modal-trigger', href: "#modal-#{model.id}") do concat(model.name.titleize) end end def model_modal(model, edit_path, options = {}) content_tag(:div, class: 'modal', id: "modal-#{model.id}") do concat(model_modal_content(model, options)) concat(model_modal_footer(model, edit_path)) end end def dynamic_model_modal(model, options = {}) model_modal_content(model, options) + model_modal_footer(model, "#{request.url}/edit") end def model_modal_content(model, options = {}) content_tag(:div, class: 'modal-content') do concat(content_tag(:h2) { model.name }) concat(content_tag(:div, class: 'row') do concat(model_modal_tabs(model, options)) concat(model_modal_fields_tab(model, options)) concat(model_modal_standard_tab(model, options)) concat(model_modal_logs_tab(model, options)) if model.respond_to?(:logs) end) end end def model_modal_tabs(model, _options = {}) content_tag(:div, class: 'col s12') do concat(content_tag(:ul, class: 'tabs tabs-fixed-width') do concat(content_tag(:li, class: 'tab') do content_tag(:a, href: "#field-tab-#{model.id}") { model.class.to_s.titleize } end) concat(content_tag(:li, class: 'tab') { content_tag(:a, href: "#standard-tab-#{model.id}") { 'Details' } }) if model.respond_to?(:logs) concat(content_tag(:li, class: 'tab') { content_tag(:a, href: "#logs-tab-#{model.id}") { 'Logs' } }) end end) end end def model_modal_standard_tab(model, options = {}) content_tag(:div, id: "standard-tab-#{model.id}", class: 'col s12') do concat(model_modal_standard(model, options)) end end def model_modal_fields_tab(model, options = {}) content_tag(:div, id: "field-tab-#{model.id}", class: 'col s12') do concat(model_modal_fields(model, options)) end end def model_modal_logs_tab(model, _options = {}) content_tag(:div, id: "logs-tab-#{model.id}", class: 'col s12') do content_tag(:table, class: 'center-align') do concat(content_tag(:thead) do concat(content_tag(:tr) do concat(content_tag(:th) { 'Created' }) concat(content_tag(:th) { 'Command' }) concat(content_tag(:th) { 'Message' }) end) end) concat(content_tag(:tbody) do model.logs.each do |log| concat(model_modal_log(log)) end end) end end end def model_modal_log(log) content_tag(:tr) do concat(content_tag(:td) { log.created_at }) concat(content_tag(:td) { log.display_message }) end end def model_modal_fields(model, _options = {}) content_tag(:table, class: 'center-align') do concat(content_tag(:tbody) do model.class.allowed_param_names.sort.each do |field_name| concat(model_modal_field(model, field_name)) end end) end end def model_modal_standard(model, _options = {}) content_tag(:table, class: 'center-align highlight') do concat(content_tag(:tbody) do %w[_id _type created_at updated_at search_text sort_text].each do |field_name| concat(model_modal_field(model, field_name)) end end) end end def model_modal_field(model, field_name) content_tag(:tr) do concat(content_tag(:th, class: 'right-align') do field_name.titleize end) concat(content_tag(:td) do model_modal_field_value(model, field_name) end) end end def model_modal_field_value(model, field_name) value = model.respond_to?(field_name) ? model.send(field_name) : '' case value when BSON::ObjectId if field_name.eql?('_id') value.to_s else related_model = fetch_related_model(model, field_name.chomp('_id')) related_model.present? ? related_model.name : 'N/A' end when FalseClass 'No' when TrueClass 'Yes' when Mongoid::Boolean, Boolean value ? 'Yes' : 'No' when Date, DateTime, Time current_user.local_time(value, :long) when Integer, Array value.to_s else value end end def model_modal_footer(model, edit_path) content_tag(:div, class: 'modal-footer') do concat(edit_modal_tag(model, edit_path)) end end end