newshound 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c59db21db9a10838f80bf529e985a4cb1af723bcf86ba4893db0d597b1a10059
4
- data.tar.gz: 66a6aa516fc12f6c7003ed286c0ffaef9fc7112c2d659b96a927b09de53c0a54
3
+ metadata.gz: 79ace59ee869878db3221ca5d851c9bf10ae50354877d6b4a2b57ccc9489319e
4
+ data.tar.gz: 9a0e6d98ce5ac41b433c19d66ae920b207c090d7550df505645068c46f627feb
5
5
  SHA512:
6
- metadata.gz: 210e8a10e784ab3a72a34291465faf6c2f213a332eca30d392561609a0316a7c28e30ae532a814bf4eca2f42fb630ed43ce8dcc4c2db458d05267fc14419c5ac
7
- data.tar.gz: 6de9641e2cfb691ccb94c4185c54dabaa78d9d92ac57e173eed5087ebb5c0dd5e468c81f79d2ca83b20376bc2d29e9137e766354028493c568c0d24eca615b07
6
+ metadata.gz: 7124a65e125a08eea643486de24db7e84436c981ccd6e9c6fa12b205b33f1e2e30b062d38c766ab0f9df18bda79fd3d093b5bfccf23b5d9938b0c45e45d6a23e
7
+ data.tar.gz: d414aa404515671d71525214ebe0f601e456c6704e5bfccf29a49246454ea9f9d83e899576db2903cfe4d0491b8255a915d6b17a4c5cdefb879d5318b0476f66
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.4.3
1
+ ruby 4.0.1
data/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.1] - 2026-03-17
9
+
10
+ ### Changed
11
+
12
+ - The authorize_with initializer will generate with the method inside the configure block. (2d6ef48)
13
+
14
+ ### Added
15
+
16
+ - Configurable banner links for exceptions, jobs, and warnings via string path patterns (1df1636)
17
+ - Record ID in format_for_banner output for linking to individual records (e06d040)
18
+
8
19
  ## [0.2.8] - 2026-02-10
9
20
 
10
21
  ### Changed
@@ -30,5 +41,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
30
41
  - Jobs::Que adapter for Que job backend (c50ba9c)
31
42
  - JobReporter that delegates to a configurable job source adapter (c50ba9c)
32
43
  - ExceptionReporter#formatted_exception_count and #exception_summary helpers (e440188)
33
-
34
- ## [0.2.7] - 2026-01-30
@@ -28,14 +28,36 @@ Newshound.configure do |config|
28
28
  # Most apps use :current_user (Devise, etc.)
29
29
  # Default is :current_user
30
30
  config.current_user_method = :current_user
31
- end
32
31
 
33
- # Advanced: Custom authorization logic
34
- # If the default role-based authorization doesn't fit your needs,
35
- # you can provide a custom authorization block:
36
- #
37
- # Newshound.authorize_with do |controller|
38
- # # Your custom logic here
39
- # # Return true to show the banner, false to hide it
40
- # controller.current_user&.admin?
41
- # end
32
+ # Links for banner items
33
+ # Configure paths so banner items link to your exception/job dashboards.
34
+ # Use :id in show paths to interpolate the record ID.
35
+ #
36
+ # config.exception_links = {
37
+ # index: "/errors",
38
+ # show: "/errors/:id"
39
+ # }
40
+ #
41
+ # config.job_links = {
42
+ # index: "/background_jobs",
43
+ # show: "/background_jobs/jobs/:id",
44
+ # scheduled: "/background_jobs/scheduled",
45
+ # failed: "/background_jobs/failed",
46
+ # completed: "/background_jobs/completed"
47
+ # }
48
+ #
49
+ # config.warning_links = {
50
+ # index: "/warnings",
51
+ # show: "/warnings/:id"
52
+ # }
53
+
54
+ # Custom authorization logic:
55
+ # If the default role-based authorization doesn't fit your needs,
56
+ # you can provide a custom authorization block:
57
+ #
58
+ # config.authorize_with do |controller|
59
+ # # Your custom logic here
60
+ # # Return true to show the banner, false to hide it
61
+ # controller.current_user&.admin?
62
+ # end
63
+ end
@@ -4,7 +4,8 @@ module Newshound
4
4
  class Configuration
5
5
  attr_accessor :exception_limit, :enabled, :authorized_roles,
6
6
  :current_user_method, :authorization_block, :exception_source,
7
- :warning_source, :warning_limit, :job_source
7
+ :warning_source, :warning_limit, :job_source,
8
+ :exception_links, :job_links, :warning_links
8
9
 
9
10
  def initialize
10
11
  @exception_limit = 10
@@ -16,6 +17,9 @@ module Newshound
16
17
  @warning_source = nil
17
18
  @warning_limit = 10
18
19
  @job_source = nil
20
+ @exception_links = {}
21
+ @job_links = {}
22
+ @warning_links = {}
19
23
  end
20
24
 
21
25
  # Allow custom authorization logic
@@ -31,7 +31,7 @@ module Newshound
31
31
  # Formats an exception for banner UI display
32
32
  #
33
33
  # @param exception [Object] Exception record from the tracking system
34
- # @return [Hash] Hash with keys: :title, :message, :location, :time
34
+ # @return [Hash] Hash with keys: :id, :title, :message, :location, :time
35
35
  def format_for_banner(exception)
36
36
  raise NotImplementedError, "#{self.class} must implement #format_for_banner"
37
37
  end
@@ -23,6 +23,7 @@ module Newshound
23
23
  details = parse_exception_details(exception)
24
24
 
25
25
  {
26
+ id: exception.try(:id),
26
27
  title: details[:title],
27
28
  message: details[:message].truncate(100),
28
29
  location: details[:location],
@@ -23,6 +23,7 @@ module Newshound
23
23
  details = parse_exception_details(exception)
24
24
 
25
25
  {
26
+ id: exception.try(:error)&.id || exception.try(:id),
26
27
  title: details[:title],
27
28
  message: details[:message].truncate(100),
28
29
  location: details[:location],
@@ -276,6 +276,20 @@ module Newshound
276
276
  text-transform: uppercase;
277
277
  letter-spacing: 0.5px;
278
278
  }
279
+ .newshound-link {
280
+ color: inherit;
281
+ text-decoration: none;
282
+ }
283
+ .newshound-link:hover {
284
+ text-decoration: underline;
285
+ }
286
+ a.newshound-stat {
287
+ color: inherit;
288
+ text-decoration: none;
289
+ }
290
+ a.newshound-stat:hover {
291
+ background: rgba(255,255,255,0.2);
292
+ }
279
293
  </style>
280
294
  CSS
281
295
  end
@@ -309,23 +323,11 @@ module Newshound
309
323
  return %(<div class="newshound-section"><div class="newshound-section-title">✅ Exceptions</div><div class="newshound-item">No exceptions in the last 24 hours</div></div>)
310
324
  end
311
325
 
312
- items = exceptions.take(5).map do |ex|
313
- <<~HTML
314
- <div class="newshound-item">
315
- <div class="newshound-item-title">#{escape_html(ex[:title])}</div>
316
- <div class="newshound-item-detail">
317
- #{escape_html(ex[:message])} • #{escape_html(ex[:location])} • #{escape_html(ex[:time])}
318
- </div>
319
- </div>
320
- HTML
321
- end.join
322
-
323
- <<~HTML
324
- <div class="newshound-section">
325
- <div class="newshound-section-title">⚠️ Recent Exceptions (#{exceptions.length})</div>
326
- #{items}
327
- </div>
328
- HTML
326
+ render_item_section(
327
+ items: exceptions,
328
+ links: Newshound.configuration.exception_links,
329
+ title: "⚠️ Recent Exceptions (#{exceptions.length})"
330
+ )
329
331
  end
330
332
 
331
333
  def render_warnings(data)
@@ -333,53 +335,81 @@ module Newshound
333
335
 
334
336
  return "" if warnings.empty?
335
337
 
336
- items = warnings.take(5).map do |w|
337
- <<~HTML
338
- <div class="newshound-item">
339
- <div class="newshound-item-title">#{escape_html(w[:title])}</div>
340
- <div class="newshound-item-detail">
341
- #{escape_html(w[:message])} • #{escape_html(w[:location])} • #{escape_html(w[:time])}
342
- </div>
338
+ render_item_section(
339
+ items: warnings,
340
+ links: Newshound.configuration.warning_links,
341
+ title: "⚠️ Warnings (#{warnings.length})"
342
+ )
343
+ end
344
+
345
+ def render_item_section(items:, links:, title:)
346
+ rendered_items = items.take(5).map do |item|
347
+ item_content = <<~HTML
348
+ <div class="newshound-item-title">#{escape_html(item[:title])}</div>
349
+ <div class="newshound-item-detail">
350
+ #{escape_html(item[:message])} • #{escape_html(item[:location])} • #{escape_html(item[:time])}
343
351
  </div>
344
352
  HTML
353
+
354
+ if links[:show] && item[:id]
355
+ url = links[:show].gsub(":id", item[:id].to_s)
356
+ %(<a href="#{escape_html(url)}" class="newshound-link"><div class="newshound-item">#{item_content}</div></a>)
357
+ else
358
+ %(<div class="newshound-item">#{item_content}</div>)
359
+ end
345
360
  end.join
346
361
 
362
+ title_html = if links[:index]
363
+ %(<a href="#{escape_html(links[:index])}" class="newshound-link">#{title}</a>)
364
+ else
365
+ title
366
+ end
367
+
347
368
  <<~HTML
348
369
  <div class="newshound-section">
349
- <div class="newshound-section-title">⚠️ Warnings (#{warnings.length})</div>
350
- #{items}
370
+ <div class="newshound-section-title">#{title_html}</div>
371
+ #{rendered_items}
351
372
  </div>
352
373
  HTML
353
374
  end
354
375
 
355
376
  def render_jobs(data)
356
377
  stats = data[:queue_stats] || {}
378
+ links = Newshound.configuration.job_links
379
+
380
+ section_title = "📊 Job Queue Status"
381
+ title_html = if links[:index]
382
+ %(<a href="#{escape_html(links[:index])}" class="newshound-link">#{section_title}</a>)
383
+ else
384
+ section_title
385
+ end
357
386
 
358
387
  <<~HTML
359
388
  <div class="newshound-section">
360
- <div class="newshound-section-title">📊 Job Queue Status</div>
389
+ <div class="newshound-section-title">#{title_html}</div>
361
390
  <div class="newshound-grid">
362
- <div class="newshound-stat">
363
- <span class="newshound-stat-value">#{stats[:ready_to_run] || 0}</span>
364
- <span class="newshound-stat-label">Ready</span>
365
- </div>
366
- <div class="newshound-stat">
367
- <span class="newshound-stat-value">#{stats[:scheduled] || 0}</span>
368
- <span class="newshound-stat-label">Scheduled</span>
369
- </div>
370
- <div class="newshound-stat">
371
- <span class="newshound-stat-value">#{stats[:failed] || 0}</span>
372
- <span class="newshound-stat-label">Failed</span>
373
- </div>
374
- <div class="newshound-stat">
375
- <span class="newshound-stat-value">#{stats[:completed_today] || 0}</span>
376
- <span class="newshound-stat-label">Completed Today</span>
377
- </div>
391
+ #{render_job_stat(stats[:ready_to_run] || 0, "Ready", links[:index])}
392
+ #{render_job_stat(stats[:scheduled] || 0, "Scheduled", links[:scheduled])}
393
+ #{render_job_stat(stats[:failed] || 0, "Failed", links[:failed])}
394
+ #{render_job_stat(stats[:completed_today] || 0, "Completed Today", links[:completed])}
378
395
  </div>
379
396
  </div>
380
397
  HTML
381
398
  end
382
399
 
400
+ def render_job_stat(value, label, link)
401
+ content = <<~HTML
402
+ <span class="newshound-stat-value">#{value}</span>
403
+ <span class="newshound-stat-label">#{label}</span>
404
+ HTML
405
+
406
+ if link
407
+ %(<a href="#{escape_html(link)}" class="newshound-stat">#{content}</a>)
408
+ else
409
+ %(<div class="newshound-stat">#{content}</div>)
410
+ end
411
+ end
412
+
383
413
  def escape_html(text)
384
414
  return +"" unless text.present?
385
415
  text.to_s
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Newshound
4
- VERSION = "1.0.0"
4
+ VERSION = "1.0.1"
5
5
  end
@@ -33,7 +33,7 @@ module Newshound
33
33
  # Formats a warning for banner UI display
34
34
  #
35
35
  # @param warning [Object] Warning record from the data source
36
- # @return [Hash] Hash with keys: :title, :message, :location, :time
36
+ # @return [Hash] Hash with keys: :id, :title, :message, :location, :time
37
37
  def format_for_banner(warning)
38
38
  raise NotImplementedError, "#{self.class} must implement #format_for_banner"
39
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newshound
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Savannah Moore
@@ -87,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
89
  requirements: []
90
- rubygems_version: 3.6.7
90
+ rubygems_version: 4.0.3
91
91
  specification_version: 4
92
92
  summary: Real-time web UI banner for monitoring background jobs and exception tracking
93
93
  test_files: []