Module: Karafka::Web::Ui::Helpers::ApplicationHelper

Included in:
Base
Defined in:
lib/karafka/web/ui/helpers/application_helper.rb

Overview

Main application helper

Instance Method Summary collapse

Instance Method Details

#flat_hash(hash, parent_key = nil, result = {}) ⇒ Hash

Parameters:

  • hash (Hash)

    we want to flatten

  • parent_key (String) (defaults to: nil)

    key for recursion

  • result (Hash) (defaults to: {})

    result for recursion

Returns:

  • (Hash)


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 235

def flat_hash(hash, parent_key = nil, result = {})
  hash.each do |key, value|
    current_key = parent_key ? "#{parent_key}.#{key}" : key.to_s
    if value.is_a?(Hash)
      flat_hash(value, current_key, result)
    elsif value.is_a?(Array)
      value.each_with_index do |item, index|
        flat_hash({ index => item }, current_key, result)
      end
    else
      result[current_key] = value
    end
  end

  result
end

#format_memory(mem_kb) ⇒ String

Returns formatted memory usage.

Parameters:

  • mem_kb (Integer)

    memory used in KB

Returns:

  • (String)

    formatted memory usage



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 92

def format_memory(mem_kb)
  return '0' if !mem_kb || mem_kb.zero?

  if mem_kb < 10_240
    "#{number_with_delimiter(mem_kb)} KB"
  elsif mem_kb < 1_000_000
    "#{number_with_delimiter((mem_kb / 1024.0).to_i)} MB"
  else
    "#{number_with_delimiter((mem_kb / (1024.0 * 1024.0)).round(1))} GB"
  end
end

#kafka_state_bg(state) ⇒ String

Takes a kafka report state and recommends background style color

Parameters:

  • state (String)

    state

Returns:

  • (String)

    background style



80
81
82
83
84
85
86
87
88
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 80

def kafka_state_bg(state)
  case state
  when 'up' then 'bg-success text-white'
  when 'active' then 'bg-success text-white'
  when 'steady' then 'bg-success text-white'
  else
    'bg-warning text-dark'
  end
end

#lag_trend_bg(trend) ⇒ String

Takes the lag trend and gives it appropriate background style color for badge

Parameters:

  • trend (Numeric)

    lag trend

Returns:

  • (String)

    bg classes



60
61
62
63
64
65
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 60

def lag_trend_bg(trend)
  bg = 'bg-success' if trend.negative?
  bg ||= 'bg-warning text-dark' if trend.positive?
  bg ||= 'bg-secondary'
  bg
end

#lag_with_label(lag) ⇒ String

Returns lag if correct or N/A with labeled explanation.

Parameters:

  • lag (Integer)

    lag

Returns:

  • (String)

    lag if correct or N/A with labeled explanation

See Also:



168
169
170
171
172
173
174
175
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 168

def lag_with_label(lag)
  if lag.negative?
    title = 'Not available until first offset commit'
    %(<span class="badge bg-secondary" title="#{title}">N/A</span>)
  else
    lag.to_s
  end
end

#lso_risk_state_bg(details) ⇒ String

Returns background classes for row marking.

Parameters:

Returns:

  • (String)

    background classes for row marking



199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 199

def lso_risk_state_bg(details)
  case details.lso_risk_state
  when :active
    ''
  when :at_risk
    'bg-warning bg-opacity-25'
  when :stopped
    'bg-danger bg-opacity-25'
  else
    raise ::Karafka::Errors::UnsupportedCaseError
  end
end

Adds active class to the current location in the nav if needed

Parameters:

  • location (Hash)


13
14
15
16
17
18
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 13

def nav_class(location)
  comparator, value = location.to_a.first

  local_location = request.path.gsub(env.fetch('SCRIPT_NAME'), '')
  local_location.public_send(:"#{comparator}?", value) ? 'active' : ''
end

#number_with_delimiter(number, delimiter = ',') ⇒ String

Converts number to a more friendly delimiter based version

Parameters:

  • number (Numeric)
  • delimiter (String) (defaults to: ',')

    delimiter (comma by default)

Returns:

  • (String)

    number with delimiter



108
109
110
111
112
113
114
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 108

def number_with_delimiter(number, delimiter = ',')
  return '' unless number

  parts = number.to_s.to_str.split('.')
  parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
  parts.join('.')
end

#object_value_to_s(object) ⇒ String

Converts object into a string and for objects that would anyhow return their stringified instance value, it replaces it with the class name instead. Useful for deserializers, etc presentation.

Parameters:

  • object (Object)

Returns:

  • (String)


26
27
28
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 26

def object_value_to_s(object)
  object.to_s.include?('#<') ? object.class.to_s : object.to_s
end

#offset_with_label(topic_name, partition_id, offset, explore: false) ⇒ String

Returns offset if correct or N/A with labeled explanation for offsets that are less than 0. Offset with less than 0 indicates, that the offset was not yet committed and there is no value we know of.

Parameters:

  • topic_name (String)

    name of the topic for explorer path

  • partition_id (Integer)

    partition for the explorer path

  • offset (Integer)

    offset

  • explore (Boolean) (defaults to: false)

    should we generate (when allowed) a link to message explorer

Returns:

  • (String)

    offset if correct or N/A with labeled explanation for offsets that are less than 0. Offset with less than 0 indicates, that the offset was not yet committed and there is no value we know of



184
185
186
187
188
189
190
191
192
193
194
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 184

def offset_with_label(topic_name, partition_id, offset, explore: false)
  if offset.negative?
    title = 'Not available until first offset commit'
    %(<span class="badge bg-secondary" title="#{title}">N/A</span>)
  elsif explore
    path = explorer_path(topic_name, partition_id, offset)
    %(<a href="#{path}">#{offset}</a>)
  else
    offset.to_s
  end
end

#poll_state_with_change_time_label(state, state_ch) ⇒ String

Returns span tag with label and title with change time if present.

Parameters:

  • state (String)

    poll state

  • state_ch (Integer)

    time until next change of the poll state (from paused to active)

Returns:

  • (String)

    span tag with label and title with change time if present



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 135

def poll_state_with_change_time_label(state, state_ch)
  year_in_seconds = 131_556_926
  state_ch_in_seconds = state_ch / 1_000.0

  # If state is active, there is no date of change
  if state == 'active'
    %(
      <span class="badge #{kafka_state_bg(state)} mt-1 mb-1">#{state}</span>
    )
  elsif state_ch_in_seconds > year_in_seconds
    %(
      <span
        class="badge #{kafka_state_bg(state)} mt-1 mb-1"
        title="until manual resume"
      >
        #{state}
      </span>
    )
  else
    %(
      <span
        class="badge #{kafka_state_bg(state)} time-title mt-1 mb-1"
        title="#{Time.now + state_ch_in_seconds}"
      >
        #{state}
      </span>
    )
  end
end

#relative_time(time) ⇒ String

Returns relative time tag for timeago.js.

Parameters:

  • time (Float)

    UTC time float

Returns:

  • (String)

    relative time tag for timeago.js



118
119
120
121
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 118

def relative_time(time)
  stamp = Time.at(time).getutc.iso8601(3)
  %(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
end

#render_breadcrumbsObject

Renders per scope breadcrumbs



31
32
33
34
35
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 31

def render_breadcrumbs
  scope = request.path.delete_prefix(root_path).split('/')[0]

  render "#{scope}/_breadcrumbs"
end

Returns html link for sorting with arrow when attribute sort enabled.

Parameters:

  • name (String)

    link value

  • attribute (Symbol, nil) (defaults to: nil)

    sorting attribute or nil if we provide only symbol name

  • rev (Boolean) (defaults to: false)

    when set to true, arrows will be in the reverse position. This is used when the description in the link is reverse to data we sort. For example we have order on when processes were started and we display “x hours” ago but we sort on their age, meaning that it looks like it is the other way around. This flag allows us to reverse just he arrow making it look consistent with the presented data order

Returns:

  • (String)

    html link for sorting with arrow when attribute sort enabled



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 260

def sort_link(name, attribute = nil, rev: false)
  unless attribute
    attribute = name
    name = attribute.to_s.tr('_', ' ').capitalize
  end

  arrow_both = '&#x21D5;'
  arrow_down = '&#9662;'
  arrow_up = '&#9652;'

  desc = "#{attribute} desc"
  asc = "#{attribute} asc"
  path = current_path(sort: desc)
  full_name = "#{name}&nbsp;#{arrow_both}"

  if params.sort == desc
    path = current_path(sort: asc)
    full_name = "#{name}&nbsp;#{rev ? arrow_up : arrow_down}"
  end

  if params.sort == asc
    path = current_path(sort: desc)
    full_name = "#{name}&nbsp;#{rev ? arrow_down : arrow_up}"
  end

  "<a class=\"sort\" href=\"#{path}\">#{full_name}</a>"
end

#status_bg(status) ⇒ String

Takes a status and recommends background style color

Parameters:

  • status (String)

    status

Returns:

  • (String)

    background style



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 41

def status_bg(status)
  case status
  when 'initialized' then 'bg-success'
  when 'supervising' then 'bg-success'
  when 'running' then 'bg-success'
  when 'quieting' then 'bg-warning'
  when 'quiet' then 'bg-warning text-dark'
  when 'stopping' then 'bg-warning text-dark'
  when 'stopped' then 'bg-danger'
  when 'terminated' then 'bg-danger'
  else
    raise ::Karafka::Errors::UnsupportedCaseError, status
  end
end

#tags(tags_array) ⇒ String

Renders tags one after another

Parameters:

  • tags_array (Array<String>)

Returns:

  • (String)

    tags badges



71
72
73
74
75
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 71

def tags(tags_array)
  tags_array
    .map { |tag| %(<span class="badge bg-info">#{tag}</span>) }
    .join(' ')
end

#time_with_label(time) ⇒ String

Returns span tag with raw timestamp as a title and time as a value.

Parameters:

  • time (Time)

    time object we want to present with detailed ms label

Returns:

  • (String)

    span tag with raw timestamp as a title and time as a value



125
126
127
128
129
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 125

def time_with_label(time)
  stamp = (time.to_f * 1000).to_i

  %(<span title="#{stamp}">#{time}</span>)
end

#view_title(title, hr: false) ⇒ String

Returns the view title html code

Parameters:

  • title (String)

    page title

  • hr (Boolean) (defaults to: false)

    should we add the hr tag at the end

Returns:

  • (String)

    title html



217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/karafka/web/ui/helpers/application_helper.rb', line 217

def view_title(title, hr: false)
  <<-HTML
    <div class="container mb-5">
      <div class="row">
        <h3>
          #{title}
        </h3>
      </div>

      #{hr ? '<hr/>' : ''}
    </div>
  HTML
end