Module: ApplicationHelper

Includes:
Informatics::Globals
Defined in:
app/helpers/application_helper.rb,
lib/informatics/lib/informatics/controller_helper.rb

Overview

rubocop:todo Style/Documentation

Instance Method Summary collapse

Methods included from Informatics::Globals

#application, #application=, #defaults, #defaults=, #global_searchable_classes, #search_options

Instance Method Details

#about(title = '') ⇒ Object

From Pipelines


163
164
165
# File 'app/helpers/application_helper.rb', line 163

def about(title = '')
  add :about, title
end

#add(type, link, options = nil) ⇒ Object

rubocop:todo Metrics/MethodLength, Metrics/AbcSize


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/informatics/lib/informatics/controller_helper.rb', line 12

def add(type, link, options = nil) # rubocop:todo Metrics/CyclomaticComplexity
  o = Informatics::Support::Options.collect(options)
  l = Informatics::Support::Options.collect(link)
  case type
  when :menu
    @menu ||= Informatics::View::Menu::List.new
    @menu = add_link(@menu, l, o, options)
  when :back_menu
    @back_menu ||= Informatics::View::Menu::List.new
    @back_menu.add_item text: l.first_key, link: l.first_value
  when :about, :title
    # Replaces :title
    @about = link
  when :legend_option
    @legend = add_link(@legend, l, o, options)
  when :tab
    @tabs = Informatics::View::Tabs::List.new unless @tabs
    @tabs.add_item text: l.first_key, link: l.first_value
  end
end

#api_dataObject


44
45
46
# File 'app/helpers/application_helper.rb', line 44

def api_data
  { api_version: RELEASE.api_version }
end

#badge(status, type: 'generic-badge', style: status) ⇒ type

Renders a badge containing the supplied text, with appropriate styling. By default the 'badge-#{status}' class is applied. These states are mapped to bootstrap colours in components.scss (grep '// State-colour extensions')

If you can't map the text directly to a style, such as if you are displaying a number that you want to change its colours at certain thresholds, then you can override the applied style with the style: argument.

If the string passed in is empty, no badge will be rendered

Examples:

Render a request state badge.

badge(request.state, type: 'request')

Render the size of a batch, which is red if too large.

status = batch.size > MAX_SIZE ? 'danger' : 'success'
badge(batch.size, type: 'batch-size', style: status )

Parameters:

  • status (String)

    The text to display in the badge. Will also be used to set the style if not otherwise specified

  • type (String) (defaults to: 'generic-badge')

    Optional: Additional css-class applied to the badge (generic-badge by default)

  • style (String) (defaults to: status)

    Optional: Override the badge-* class otherwise set directly from the status.

Returns:

  • (type)

    HTML to render a badge


85
86
87
88
89
# File 'app/helpers/application_helper.rb', line 85

def badge(status, type: 'generic-badge', style: status)
  return if status.blank?

  tag.span(status, class: "#{type} badge badge-#{style}")
end

#counter_badge(counter, suffix = '') ⇒ String

Used to add a counter to headers or links. Renders a blue badge containing the supplied number Only supply a suffix if it can't be worked out from the context what is being counted.

Parameters:

  • counter (Integer)

    The value to show in the badge

  • suffix (Integer, String) (defaults to: '')

    Optional: The type of thing being counted.

Returns:

  • (String)

    HTML to render a badge


98
99
100
101
# File 'app/helpers/application_helper.rb', line 98

def counter_badge(counter, suffix = '')
  status = suffix.present? ? pluralize(counter, suffix) : counter
  badge(status, type: 'counter-badge', style: 'primary')
end

#custom_text(identifier, differential = nil) ⇒ Object

Should return either the custom text or a blank string


5
6
7
8
9
10
11
12
13
# File 'app/helpers/application_helper.rb', line 5

def custom_text(identifier, differential = nil)
  Rails
    .cache
    .fetch("#{identifier}-#{differential}") do
      custom_text = CustomText.find_by(identifier: identifier, differential: differential)

      custom_text.try(:content) || ''
    end
end

#display_boolean_results(result) ⇒ Object


219
220
221
222
223
224
225
226
227
# File 'app/helpers/application_helper.rb', line 219

def display_boolean_results(result)
  return 'NA' if result.blank?

  if result == 'pass' || result == '1' || result == 'true'
    icon('far', 'check-circle', title: result)
  else
    icon('fas', 'exclamation-circle', class: 'text-danger', title: result)
  end
end

#display_follow(item, user, msg) ⇒ Object


157
158
159
# File 'app/helpers/application_helper.rb', line 157

def display_follow(item, user, msg)
  user.follower_of?(item) ? 'Unfollow ' + msg : 'Follow ' + msg
end

#display_user_error(display_text, link = nil) ⇒ Object


58
59
60
# File 'app/helpers/application_helper.rb', line 58

def display_user_error(display_text, link = nil)
  alert(:danger) { link.present? ? link_to(display_text, link) : display_text }
end

#display_user_guide(display_text, link = nil) ⇒ type

Renders a user guide with optional link. Applies appropriate styling

Parameters:

  • display_text (String)

    The text of the user guide

  • link (String) (defaults to: nil)

    Optional url to link the guide to.

Returns:

  • (type)
    description

54
55
56
# File 'app/helpers/application_helper.rb', line 54

def display_user_guide(display_text, link = nil)
  alert(:user_guide) { concat link.present? ? link_to(display_text, link) : display_text }
end

rubocop:todo Metrics/MethodLength


104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/helpers/application_helper.rb', line 104

def dynamic_link_to(summary_item) # rubocop:todo Metrics/AbcSize
  object = summary_item.object
  if object.instance_of?(Submission)
    link_to("Submission #{object.id}", study_information_submission_path(object.study, object))
  elsif object.instance_of?(Receptacle)
    link_to("#{object.label.capitalize} #{object.name}", receptacle_path(object))
  elsif object.instance_of?(Labware)
    link_to("#{object.label.capitalize} #{object.name}", labware_path(object))
  elsif object.instance_of?(Request)
    link_to("Request #{object.id}", request_path(object))
  else
    'No link available'
  end
end

The admin email address should be stored in config.yml for the current environment


252
253
254
255
# File 'app/helpers/application_helper.rb', line 252

def help_email_link
  admin_address = configatron.admin_email || '[email protected]'
  link_to admin_address.to_s, "mailto:#{admin_address}"
end

245
246
247
248
249
# File 'app/helpers/application_helper.rb', line 245

def help_link(text, entry = '', options = {})
  url = "#{configatron.help_link_base_url}/#{entry}"
  options[:class] = "#{options[:class]} external_help"
  link_to text, url, options
end

#help_text(&block) ⇒ Object


241
242
243
# File 'app/helpers/application_helper.rb', line 241

def help_text(&block)
  tag.small(class: 'form-text text-muted col', &block)
end

#hidden_label_tag_for_testing(name, text = nil, options = {}) ⇒ Object

Creates a label that is hidden from the view so that testing is easier


237
238
239
# File 'app/helpers/application_helper.rb', line 237

def hidden_label_tag_for_testing(name, text = nil, options = {})
  label_tag(name, text, options.merge(style: 'display:none;'))
end

#loggerObject

rubocop:enable Metrics/AbcSize, Metrics/MethodLength


35
36
37
# File 'lib/informatics/lib/informatics/controller_helper.rb', line 35

def logger
  Rails.logger
end

#old_urlObject

Used in _header.html.erb. Can be removed after users have been given a time period to switch over.


293
294
295
296
297
298
299
300
301
# File 'app/helpers/application_helper.rb', line 293

def old_url
  permitted_urls = %w[
    http://sequencescape.psd.sanger.ac.uk
    http://uat.sequencescape.psd.sanger.ac.uk
    http://uat2.sequencescape.psd.sanger.ac.uk
    http://training.sequencescape.psd.sanger.ac.uk
  ]
  return true unless permitted_urls.include?(request.base_url)
end

#remote_error(identifier = 'remote_error') ⇒ Object

TODO:

Probably remove this and the references to it in app/views/studies/information/_items.html.erb Or possibly restore the intended behaviour in app/assets/javascripts/sequencescape/ajax_link_handling.js

Renders a non-displayed error div warning of a data failure Appears to have been intended to be used to provide error feedback on the studies in app/views/studies/information/_items.html.erb but actual behaviour will result in the error payload being placed in the div, but remaining invisible.

Parameters:

  • identifier (String) (defaults to: 'remote_error')

    The id of the element


24
25
26
27
28
# File 'app/helpers/application_helper.rb', line 24

def remote_error(identifier = 'remote_error')
  tag.div(id: identifier, class: 'error', style: 'display:none;') do
    'An error has occurred and the results can not be shown at the moment'
  end
end

#render_flashesObject


37
38
39
40
41
42
# File 'app/helpers/application_helper.rb', line 37

def render_flashes
  flash.each do |key, message|
    concat(alert(key, id: "message_#{key}") { Array(message).each { |m| concat tag.div(m) } })
  end
  nil
end

#render_parsed_json(json) ⇒ String

Handles rendering of JSON to a series of nested lists. Does the following: String: Rendered as-is Array: Unordered list (Strictly speaking arrays are ordered, but we probably don't care.) Object: Descriptive list Other: Calls to_s Processes each in turn and called recursively

rubocop:todo Metrics/MethodLength

Parameters:

  • json (Hash, String, Array, , #to_s)

    The Object to render

Returns:

  • (String)

    HTML formatted for rendering


270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'app/helpers/application_helper.rb', line 270

def render_parsed_json(json) # rubocop:todo Metrics/AbcSize
  case json
  when String
    json
  when Array
    tag.ul { json.each { |elem, _string| concat tag.li(render_parsed_json(elem)) } }
  when Hash
    tag.dl do
      json.each do |key, value|
        # Strictly speaking json should only have strings as keys. But the same constraint doesn't apply to hashes,
        # so we're a little more permissive here for flexibilities sake
        concat tag.dt(render_parsed_json(key))
        concat tag.dd(render_parsed_json(value))
      end
    end
  else
    json.to_s
  end
end

rubocop:enable Metrics/MethodLength


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/helpers/application_helper.rb', line 121

def request_count_link(study, asset, state, request_type) # rubocop:todo Metrics/AbcSize
  matching_requests =
    asset.requests.select { |request| (request.request_type_id == request_type.id) and request.state == state }
  html_options, count = { title: "#{asset.try(:human_barcode) || asset.id} #{state}" }, matching_requests.size

  # 0 requests => no link, just '0'
  # 1 request  => request summary page
  # N requests => summary overview
  if count == 1
    url_path = request_path(matching_requests.first)
    link_to count, url_path, html_options
  elsif count > 1
    url_path = study_requests_path(study, state: state, request_type_id: request_type.id, asset_id: asset.id)
    link_to count, url_path, html_options
  end
end

rubocop:todo Metrics/ParameterLists


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

def request_link(object, count, request_type, status = nil, options = {}, link_options = {})
  # rubocop:enable Metrics/ParameterLists
  link_to_if((count != 0), count, request_list_path(object, request_type, status, options), link_options)
end

#request_list_path(object, request_type = nil, status = nil, options = {}) ⇒ Object


144
145
146
147
148
149
150
151
152
153
154
155
# File 'app/helpers/application_helper.rb', line 144

def request_list_path(object, request_type = nil, status = nil, options = {})
  options[:state] = status unless status.nil?
  options[:request_type_id] = request_type.id unless request_type.nil?

  if object.instance_of?(Receptacle)
    receptacle_path(object, options)
  elsif object.instance_of?(Labware)
    labware_path(object, options)
  elsif object.instance_of?(Study)
    study_requests_path(object, options)
  end
end

#required_markerString

Inserts the icon used to indicate a field is required. This will also be displayed on any <label> tags with the .required class

Returns:

  • (String)

    HTML representing the required marker


33
34
35
# File 'app/helpers/application_helper.rb', line 33

def required_marker
  icon('fas', 'asterisk', class: 'text-warning', title: 'required')
end

#sorted_requests_for_search(requests) ⇒ Object


229
230
231
232
233
234
# File 'app/helpers/application_helper.rb', line 229

def sorted_requests_for_search(requests)
  sorted_requests = requests.select { |r| r.pipeline_id.nil? }
  new_requests = requests - sorted_requests
  new_requests.sort_by(&:pipeline_id)
  requests = requests + sorted_requests
end

#tab(name, target: nil, active: false, id: nil) ⇒ Object

<li class=“nav-item”>

<a class="nav-link <active>" id="name-tab" data-toggle="tab" href="#name"
 role="tab" aria-controls="name" aria-selected="true">name</a>

</li>


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/helpers/application_helper.rb', line 186

def tab(name, target: nil, active: false, id: nil)
  target ||= name.parameterize
  active_class = active ? 'active' : ''
  id ||= "#{name}-tab".parameterize
  tag.li(class: 'nav-item') do
    link_to name,
            "##{target}",
            id: id,
            data: {
              toggle: 'tab'
            },
            role: 'tab',
            aria_controls: target,
            class: ['nav-link', active_class]
  end
end

#tab_pane(name, id: nil, tab_id: nil, active: false, &block) ⇒ Object

<div class=“tab-pane fade show <active>” id=“pending” role=“tabpanel” aria-labelledby=“peding-tab”>

yield

</div>


206
207
208
209
210
211
212
213
214
215
216
217
# File 'app/helpers/application_helper.rb', line 206

def tab_pane(name, id: nil, tab_id: nil, active: false, &block)
  tab_id ||= "#{name}-tab".parameterize
  id ||= name.parameterize
  active_class = active ? 'active' : ''
  tag.div(
    class: ['tab-pane', 'fade', 'show', active_class],
    id: id,
    role: 'tabpanel',
    aria_labelledby: tab_id,
    &block
  )
end

#tabulated_error_messages_for(*params) ⇒ Object

rubocop:todo Metrics/AbcSize


167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'app/helpers/application_helper.rb', line 167

def tabulated_error_messages_for(*params) # rubocop:todo Metrics/AbcSize
  options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
  objects = params.filter_map { |object_name| instance_variable_get("@#{object_name}") }
  count = objects.inject(0) { |sum, object| sum + object.errors.count }
  if count.zero?
    ''
  else
    error_messages = objects.map { |object| object.errors.full_messages.map { |msg| tag.div(msg) } }.join
    [
      tag.td(class: 'error item') { "Your #{params.first} has not been created." },
      tag.td(class: 'error') { raw(error_messages) }
    ].join.html_safe
  end
end