Module: ModelModalHelper

Defined in:
app/helpers/model_modal_helper.rb

Overview

Helper to create a modal dialog for a given model

Instance Method Summary collapse

Instance Method Details

#dynamic_model_modal(model, options = {}) ⇒ Object



89
90
91
# File 'app/helpers/model_modal_helper.rb', line 89

def dynamic_model_modal(model, options = {})
  model_modal_content(model, options) + model_modal_footer(model, "#{request.url}/edit")
end

Only show the trigger with the edit path, let the rest be generated later



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'app/helpers/model_modal_helper.rb', line 23

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
  (:div) do
    concat((:a, href: "##{anchor_id}", class: 'modal-trigger') do
      concat((:span, title))
    end)
    concat((:div, id: anchor_id, class: 'modal', data: datum) do
      concat((:div, class: 'modal-content') do
        concat((:h2, class: 'center') do
          concat((:span, related_model.name))
        end)
        concat((:div, class: 'center-align') do
          concat((: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

#edit_modal_tag(obj, path, _options = {}) ⇒ Object



238
239
240
241
242
243
244
245
# File 'app/helpers/model_modal_helper.rb', line 238

def edit_modal_tag(obj, path, _options = {})
  return unless can? :edit, obj

  (:a, href: path, class: 'btn btn-primary modal-action') do
    concat(I18n.t('ui_form.actions.edit'))
    concat(svg_icon(:edit, classes: %w[ms-2]))
  end
end


57
58
59
60
61
62
# File 'app/helpers/model_modal_helper.rb', line 57

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

#model_modal(model, edit_path, options = {}) ⇒ Object



77
78
79
80
81
# File 'app/helpers/model_modal_helper.rb', line 77

def model_modal(model, edit_path, options = {})
  (:div, class: 'modal', id: "modal-#{model.id}", tabindex: -1) do
    concat(model_modal_dialog(model, edit_path, options))
  end
end

#model_modal_action(model, _options = {}) ⇒ Object



71
72
73
74
75
# File 'app/helpers/model_modal_helper.rb', line 71

def model_modal_action(model, _options = {})
  (:a, href: '#', data: { bs_toggle: :modal, bs_target: "#modal-#{model.id}" }) do
    concat(model.name)
  end
end

#model_modal_body(model, edit_path, options = {}) ⇒ Object



108
109
110
111
112
113
# File 'app/helpers/model_modal_helper.rb', line 108

def model_modal_body(model, edit_path, options = {})
  concat((:div, class: 'model-body') do
    concat(model_modal_tabs(model, options))
    concat(model_modal_tab_content(model, options))
  end)
end

#model_modal_content(model, edit_path, options = {}) ⇒ Object



93
94
95
96
97
98
99
# File 'app/helpers/model_modal_helper.rb', line 93

def model_modal_content(model, edit_path, options = {})
  (:div, class: 'modal-content') do
    concat(model_modal_header(model, edit_path, options))
    model_modal_body(model, edit_path, options)
    concat(model_modal_footer(model, edit_path))
  end
end

#model_modal_dialog(model, edit_path, options = {}) ⇒ Object



83
84
85
86
87
# File 'app/helpers/model_modal_helper.rb', line 83

def model_modal_dialog(model, edit_path, options = {})
  (:div, class: 'modal-dialog', role: :document) do
    concat(model_modal_content(model, edit_path, options))
  end
end

#model_modal_field(model, field_name) ⇒ Object



196
197
198
199
200
201
# File 'app/helpers/model_modal_helper.rb', line 196

def model_modal_field(model, field_name)
  (:div, class: 'datagrid-item') do
    concat((:div, class: 'datagrid-title') { field_name })
    concat((:div, class: 'datagrid-content') { model_modal_field_value(model, field_name) })
  end
end

#model_modal_field_value(model, field_name) ⇒ Object



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'app/helpers/model_modal_helper.rb', line 203

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
    svg_icon(:x, color: :red)
  when TrueClass
    svg_icon(:check, color: :green)
  when Mongoid::Boolean
    value ? svg_icon(:check, color: :green) : svg_icon(:x, color: :red)
  when Date, DateTime, Time
    current_user.local_time(value, :long)
  when Integer, Array, Hash, Float
    value.to_s
  else
    value
  end
end

#model_modal_fields(model, _options = {}) ⇒ Object



177
178
179
180
181
182
183
184
185
186
# File 'app/helpers/model_modal_helper.rb', line 177

def model_modal_fields(model, _options = {})
  (:div, class: 'datagrid m-2') do
    field_names = ((model.class.allowed_param_names) + %w(description name)).uniq.sort
    field_names.each do |field_name|
      next if model.respond_to?(field_name) && model.send(field_name).blank?

      concat(model_modal_field(model, field_name))
    end
  end
end

#model_modal_fields_tab(model, options = {}) ⇒ Object



145
146
147
148
149
# File 'app/helpers/model_modal_helper.rb', line 145

def model_modal_fields_tab(model, options = {})
  (:div, id: "field-tab-#{model.id}", class: 'tab-pane active', role: :tabpanel) do
    concat(model_modal_fields(model, options))
  end
end


228
229
230
231
232
233
234
235
236
# File 'app/helpers/model_modal_helper.rb', line 228

def model_modal_footer(model, edit_path)
  (:div, class: 'modal-footer') do
    concat((:button, class: 'btn me-auto', data: { bs_dismiss: :modal }) do
      concat(I18n.t('ui_form.actions.close'))
      concat(svg_icon(:close, classes: %w[ms-2]))
    end)
    concat(edit_modal_tag(model, edit_path))
  end
end

#model_modal_header(model, edit_path, options = {}) ⇒ Object



101
102
103
104
105
106
# File 'app/helpers/model_modal_helper.rb', line 101

def model_modal_header(model, edit_path, options = {})
  (:div, class: 'modal-header') do
    concat((:h2) { model.name.titleize })
    concat(tag(:button, class: 'btn-close', data: { bs_dismiss: :modal }, aria_label: :close))
  end
end

#model_modal_log(log) ⇒ Object



170
171
172
173
174
175
# File 'app/helpers/model_modal_helper.rb', line 170

def model_modal_log(log)
  (:tr) do
    concat((:td) { log.created_at })
    concat((:td) { log.display_message })
  end
end

#model_modal_logs_tab(model, _options = {}) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'app/helpers/model_modal_helper.rb', line 151

def model_modal_logs_tab(model, _options = {})
  (:div, id: "logs-tab-#{model.id}", class: 'col s12') do
    (:table, class: 'center-align') do
      concat((:thead) do
        concat((:tr) do
          concat((:th) { 'Created' })
          concat((:th) { 'Command' })
          concat((:th) { 'Message' })
        end)
      end)
      concat((:tbody) do
        model.logs.each do |log|
          concat(model_modal_log(log))
        end
      end)
    end
  end
end

#model_modal_standard_fields(model, _options = {}) ⇒ Object



188
189
190
191
192
193
194
# File 'app/helpers/model_modal_helper.rb', line 188

def model_modal_standard_fields(model, _options = {})
  (:div, class: 'datagrid m-2') do
    model.class::STANDARD_FIELDS.each do |field_name|
      concat(model_modal_field(model, field_name))
    end
  end
end

#model_modal_standard_tab(model, options = {}) ⇒ Object



139
140
141
142
143
# File 'app/helpers/model_modal_helper.rb', line 139

def model_modal_standard_tab(model, options = {})
  (:div, id: "standard-tab-#{model.id}", class: 'tab-pane', role: :tabpanel) do
    concat(model_modal_standard_fields(model, options))
  end
end

#model_modal_tab_content(model, options = {}) ⇒ Object



131
132
133
134
135
136
137
# File 'app/helpers/model_modal_helper.rb', line 131

def model_modal_tab_content(model, options = {})
  (:div, class: 'tab-content') do
    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) && options[:show_audit_logs]
  end
end

#model_modal_tabs(model, _options = {}) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/helpers/model_modal_helper.rb', line 115

def model_modal_tabs(model, _options = {})
  (:ul, class: 'nav nav-tabs', data: { bs_toggle: :tabs }) do
    concat((:li, class: 'nav-item') do
      (:a, class: 'nav-link active', href: "#field-tab-#{model.id}", data: { bs_toggle: :tab }) { model.class.to_s.titleize }
    end)
    concat((:li, class: 'nav-item') do
      (:a, class: 'nav-link', href: "#standard-tab-#{model.id}", data: { bs_toggle: :tab }) { 'Details' }
    end)
    if model.respond_to?(:logs)
      concat((:li, class: 'nav-item') do
        (:a, class: 'nav-item', href: "#logs-tab-#{model.id}", data: { bs_toggler: :tab }) { 'Logs' }
      end)
    end
  end
end

#model_modal_tag(model, edit_path, options = {}) ⇒ Object

Render a modal tag for the given model object



67
68
69
# File 'app/helpers/model_modal_helper.rb', line 67

def model_modal_tag(model, edit_path, options = {})
  model_modal_action(model, options) + model_modal(model, edit_path, options)
end

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.



13
14
15
16
17
18
# File 'app/helpers/model_modal_helper.rb', line 13

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


48
49
50
51
52
53
54
55
# File 'app/helpers/model_modal_helper.rb', line 48

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