source_monitor 0.2.0 → 0.3.0

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.
Files changed (196) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/agents/rails-concern.md +464 -0
  3. data/.claude/agents/rails-controller.md +424 -0
  4. data/.claude/agents/rails-hotwire.md +446 -0
  5. data/.claude/agents/rails-implement.md +374 -0
  6. data/.claude/agents/rails-job.md +334 -0
  7. data/.claude/agents/rails-lint.md +294 -0
  8. data/.claude/agents/rails-mailer.md +371 -0
  9. data/.claude/agents/rails-migration.md +449 -0
  10. data/.claude/agents/rails-model.md +420 -0
  11. data/.claude/agents/rails-policy.md +443 -0
  12. data/.claude/agents/rails-presenter.md +427 -0
  13. data/.claude/agents/rails-query.md +412 -0
  14. data/.claude/agents/rails-review.md +490 -0
  15. data/.claude/agents/rails-service.md +458 -0
  16. data/.claude/agents/rails-state-records.md +465 -0
  17. data/.claude/agents/rails-tdd.md +314 -0
  18. data/.claude/agents/rails-test.md +441 -0
  19. data/.claude/agents/rails-view-component.md +418 -0
  20. data/.claude/hooks/block-secrets.sh +52 -0
  21. data/.claude/settings.json +85 -0
  22. data/.claude/skills/action-cable-patterns/SKILL.md +296 -0
  23. data/.claude/skills/action-mailer-patterns/SKILL.md +295 -0
  24. data/.claude/skills/active-storage-setup/SKILL.md +311 -0
  25. data/.claude/skills/api-versioning/SKILL.md +294 -0
  26. data/.claude/skills/authentication-flow/SKILL.md +335 -0
  27. data/.claude/skills/authentication-flow/reference/current.md +248 -0
  28. data/.claude/skills/authentication-flow/reference/passwordless.md +253 -0
  29. data/.claude/skills/authentication-flow/reference/sessions.md +201 -0
  30. data/.claude/skills/authorization-pundit/SKILL.md +462 -0
  31. data/.claude/skills/caching-strategies/SKILL.md +350 -0
  32. data/.claude/skills/database-migrations/SKILL.md +354 -0
  33. data/.claude/skills/form-object-patterns/SKILL.md +399 -0
  34. data/.claude/skills/hotwire-patterns/SKILL.md +247 -0
  35. data/.claude/skills/hotwire-patterns/reference/stimulus.md +307 -0
  36. data/.claude/skills/hotwire-patterns/reference/tailwind-integration.md +112 -0
  37. data/.claude/skills/hotwire-patterns/reference/turbo-frames.md +158 -0
  38. data/.claude/skills/hotwire-patterns/reference/turbo-streams.md +218 -0
  39. data/.claude/skills/i18n-patterns/SKILL.md +320 -0
  40. data/.claude/skills/install/SKILL.md +367 -0
  41. data/.claude/skills/performance-optimization/SKILL.md +311 -0
  42. data/.claude/skills/rails-architecture/SKILL.md +259 -0
  43. data/.claude/skills/rails-architecture/reference/error-handling.md +333 -0
  44. data/.claude/skills/rails-architecture/reference/event-tracking.md +142 -0
  45. data/.claude/skills/rails-architecture/reference/layer-interactions.md +417 -0
  46. data/.claude/skills/rails-architecture/reference/multi-tenancy.md +152 -0
  47. data/.claude/skills/rails-architecture/reference/query-patterns.md +342 -0
  48. data/.claude/skills/rails-architecture/reference/service-patterns.md +286 -0
  49. data/.claude/skills/rails-architecture/reference/state-records.md +250 -0
  50. data/.claude/skills/rails-architecture/reference/testing-strategy.md +326 -0
  51. data/.claude/skills/rails-concern/SKILL.md +399 -0
  52. data/.claude/skills/rails-controller/SKILL.md +336 -0
  53. data/.claude/skills/rails-model-generator/SKILL.md +321 -0
  54. data/.claude/skills/rails-model-generator/reference/validations.md +298 -0
  55. data/.claude/skills/rails-presenter/SKILL.md +274 -0
  56. data/.claude/skills/rails-query-object/SKILL.md +289 -0
  57. data/.claude/skills/rails-service-object/SKILL.md +349 -0
  58. data/.claude/skills/solid-queue-setup/SKILL.md +307 -0
  59. data/.claude/skills/tdd-cycle/SKILL.md +359 -0
  60. data/.claude/skills/viewcomponent-patterns/SKILL.md +333 -0
  61. data/.gitignore +1 -0
  62. data/.rubocop.yml +2 -0
  63. data/.ruby-version +1 -1
  64. data/.vbw-planning/.notification-log.jsonl +192 -0
  65. data/.vbw-planning/.session-log.jsonl +871 -0
  66. data/.vbw-planning/PROJECT.md +51 -0
  67. data/.vbw-planning/REQUIREMENTS.md +50 -0
  68. data/.vbw-planning/SHIPPED.md +28 -0
  69. data/.vbw-planning/codebase/ARCHITECTURE.md +147 -0
  70. data/.vbw-planning/codebase/CONCERNS.md +99 -0
  71. data/.vbw-planning/codebase/CONVENTIONS.md +97 -0
  72. data/.vbw-planning/codebase/DEPENDENCIES.md +100 -0
  73. data/.vbw-planning/codebase/INDEX.md +86 -0
  74. data/.vbw-planning/codebase/META.md +42 -0
  75. data/.vbw-planning/codebase/PATTERNS.md +262 -0
  76. data/.vbw-planning/codebase/STACK.md +101 -0
  77. data/.vbw-planning/codebase/STRUCTURE.md +324 -0
  78. data/.vbw-planning/codebase/TESTING.md +154 -0
  79. data/.vbw-planning/config.json +12 -0
  80. data/.vbw-planning/discovery.json +24 -0
  81. data/.vbw-planning/milestones/default/ROADMAP.md +115 -0
  82. data/.vbw-planning/milestones/default/STATE.md +83 -0
  83. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01-SUMMARY.md +56 -0
  84. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01.md +187 -0
  85. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02-SUMMARY.md +64 -0
  86. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02.md +137 -0
  87. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01-SUMMARY.md +67 -0
  88. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01.md +142 -0
  89. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02-SUMMARY.md +64 -0
  90. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02.md +138 -0
  91. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03-SUMMARY.md +85 -0
  92. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03.md +147 -0
  93. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04-SUMMARY.md +63 -0
  94. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04.md +129 -0
  95. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05-SUMMARY.md +74 -0
  96. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05.md +154 -0
  97. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION-wave1.md +303 -0
  98. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION.md +510 -0
  99. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01-SUMMARY.md +61 -0
  100. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01.md +161 -0
  101. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02-SUMMARY.md +66 -0
  102. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02.md +132 -0
  103. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03-SUMMARY.md +59 -0
  104. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03.md +171 -0
  105. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04-SUMMARY.md +56 -0
  106. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04.md +152 -0
  107. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/04-CONTEXT.md +33 -0
  108. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01-SUMMARY.md +42 -0
  109. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01.md +119 -0
  110. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02-SUMMARY.md +52 -0
  111. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02.md +195 -0
  112. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03-SUMMARY.md +79 -0
  113. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03.md +130 -0
  114. data/CHANGELOG.md +28 -0
  115. data/CLAUDE.md +179 -0
  116. data/Gemfile +8 -0
  117. data/Gemfile.lock +114 -101
  118. data/Rakefile +2 -0
  119. data/app/assets/builds/source_monitor/application.css +2076 -0
  120. data/app/assets/builds/source_monitor/application.js +2758 -0
  121. data/app/assets/builds/source_monitor/application.js.map +7 -0
  122. data/app/controllers/source_monitor/application_controller.rb +2 -0
  123. data/app/controllers/source_monitor/health_controller.rb +2 -0
  124. data/app/controllers/source_monitor/import_sessions/bulk_configuration.rb +106 -0
  125. data/app/controllers/source_monitor/import_sessions/entry_annotation.rb +187 -0
  126. data/app/controllers/source_monitor/import_sessions/health_check_management.rb +112 -0
  127. data/app/controllers/source_monitor/import_sessions/opml_parser.rb +130 -0
  128. data/app/controllers/source_monitor/import_sessions_controller.rb +6 -507
  129. data/app/controllers/source_monitor/items_controller.rb +2 -0
  130. data/app/controllers/source_monitor/sources_controller.rb +0 -14
  131. data/app/helpers/source_monitor/application_helper.rb +4 -112
  132. data/app/helpers/source_monitor/health_badge_helper.rb +69 -0
  133. data/app/helpers/source_monitor/table_sort_helper.rb +53 -0
  134. data/app/jobs/source_monitor/application_job.rb +2 -0
  135. data/app/models/source_monitor/application_record.rb +2 -0
  136. data/app/models/source_monitor/log_entry.rb +0 -2
  137. data/config/coverage_baseline.json +217 -1862
  138. data/config/routes.rb +2 -0
  139. data/db/migrate/20251009103000_add_feed_content_readability_to_sources.rb +2 -0
  140. data/db/migrate/20251014171659_add_performance_indexes.rb +2 -0
  141. data/db/migrate/20251014172525_add_fetch_status_check_constraint.rb +2 -0
  142. data/db/migrate/20251108120116_refresh_fetch_status_constraint.rb +2 -0
  143. data/db/migrate/20260210204022_add_composite_index_to_log_entries.rb +17 -0
  144. data/lib/source_monitor/assets/bundler.rb +2 -0
  145. data/lib/source_monitor/assets.rb +2 -0
  146. data/lib/source_monitor/configuration/authentication_settings.rb +62 -0
  147. data/lib/source_monitor/configuration/events.rb +60 -0
  148. data/lib/source_monitor/configuration/fetching_settings.rb +27 -0
  149. data/lib/source_monitor/configuration/health_settings.rb +27 -0
  150. data/lib/source_monitor/configuration/http_settings.rb +43 -0
  151. data/lib/source_monitor/configuration/model_definition.rb +108 -0
  152. data/lib/source_monitor/configuration/models.rb +36 -0
  153. data/lib/source_monitor/configuration/realtime_settings.rb +95 -0
  154. data/lib/source_monitor/configuration/retention_settings.rb +45 -0
  155. data/lib/source_monitor/configuration/scraper_registry.rb +67 -0
  156. data/lib/source_monitor/configuration/scraping_settings.rb +39 -0
  157. data/lib/source_monitor/configuration/validation_definition.rb +32 -0
  158. data/lib/source_monitor/configuration.rb +12 -579
  159. data/lib/source_monitor/dashboard/queries/recent_activity_query.rb +138 -0
  160. data/lib/source_monitor/dashboard/queries/stats_query.rb +71 -0
  161. data/lib/source_monitor/dashboard/queries.rb +2 -195
  162. data/lib/source_monitor/engine.rb +2 -0
  163. data/lib/source_monitor/fetching/feed_fetcher/adaptive_interval.rb +141 -0
  164. data/lib/source_monitor/fetching/feed_fetcher/entry_processor.rb +89 -0
  165. data/lib/source_monitor/fetching/feed_fetcher/source_updater.rb +200 -0
  166. data/lib/source_monitor/fetching/feed_fetcher.rb +37 -379
  167. data/lib/source_monitor/items/item_creator/content_extractor.rb +113 -0
  168. data/lib/source_monitor/items/item_creator/entry_parser/media_extraction.rb +96 -0
  169. data/lib/source_monitor/items/item_creator/entry_parser.rb +294 -0
  170. data/lib/source_monitor/items/item_creator.rb +28 -455
  171. data/lib/source_monitor/setup/bundle_installer.rb +2 -0
  172. data/lib/source_monitor/setup/cli.rb +2 -0
  173. data/lib/source_monitor/setup/dependency_checker.rb +2 -0
  174. data/lib/source_monitor/setup/detectors.rb +2 -0
  175. data/lib/source_monitor/setup/gemfile_editor.rb +2 -0
  176. data/lib/source_monitor/setup/initializer_patcher.rb +2 -0
  177. data/lib/source_monitor/setup/install_generator.rb +2 -0
  178. data/lib/source_monitor/setup/migration_installer.rb +2 -0
  179. data/lib/source_monitor/setup/node_installer.rb +2 -0
  180. data/lib/source_monitor/setup/prompter.rb +2 -0
  181. data/lib/source_monitor/setup/requirements.rb +2 -0
  182. data/lib/source_monitor/setup/shell_runner.rb +2 -0
  183. data/lib/source_monitor/setup/verification/action_cable_verifier.rb +2 -0
  184. data/lib/source_monitor/setup/verification/printer.rb +2 -0
  185. data/lib/source_monitor/setup/verification/result.rb +2 -0
  186. data/lib/source_monitor/setup/verification/runner.rb +2 -0
  187. data/lib/source_monitor/setup/verification/solid_queue_verifier.rb +2 -0
  188. data/lib/source_monitor/setup/verification/telemetry_logger.rb +2 -0
  189. data/lib/source_monitor/setup/workflow.rb +2 -0
  190. data/lib/source_monitor/version.rb +3 -1
  191. data/lib/source_monitor.rb +140 -58
  192. data/lib/tasks/source_monitor_assets.rake +2 -0
  193. data/lib/tasks/source_monitor_setup.rake +2 -0
  194. data/lib/tasks/source_monitor_tasks.rake +2 -0
  195. data/source_monitor.gemspec +3 -1
  196. metadata +144 -4
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SourceMonitor
2
4
  module ApplicationHelper
5
+ include TableSortHelper
6
+ include HealthBadgeHelper
3
7
  def source_monitor_stylesheet_bundle_tag
4
8
  stylesheet_link_tag("source_monitor/application", "data-turbo-track": "reload")
5
9
  rescue StandardError => error
@@ -191,118 +195,6 @@ module SourceMonitor
191
195
  end
192
196
  end
193
197
 
194
- def source_health_badge(source, override: nil)
195
- return override if override.present?
196
-
197
- status = source&.health_status.presence || "healthy"
198
-
199
- mapping = {
200
- "healthy" => { label: "Healthy", classes: "bg-green-100 text-green-700", show_spinner: false },
201
- "warning" => { label: "Needs Attention", classes: "bg-amber-100 text-amber-700", show_spinner: false },
202
- "critical" => { label: "Failing", classes: "bg-rose-100 text-rose-700", show_spinner: false },
203
- "declining" => { label: "Declining", classes: "bg-orange-100 text-orange-700", show_spinner: false },
204
- "improving" => { label: "Improving", classes: "bg-sky-100 text-sky-700", show_spinner: false },
205
- "auto_paused" => { label: "Auto-Paused", classes: "bg-amber-100 text-amber-700", show_spinner: false },
206
- "unknown" => { label: "Unknown", classes: "bg-slate-100 text-slate-600", show_spinner: false }
207
- }
208
-
209
- mapping.fetch(status) { mapping.fetch("unknown") }.merge(status: status)
210
- end
211
-
212
- def source_health_actions(source)
213
- status = source&.health_status.presence || "healthy"
214
- helpers = SourceMonitor::Engine.routes.url_helpers
215
-
216
- case status
217
- when "critical", "declining"
218
- [
219
- {
220
- key: :full_fetch,
221
- label: "Queue Full Fetch",
222
- description: "Runs the full fetch pipeline immediately and updates items if the feed responds.",
223
- path: helpers.source_fetch_path(source),
224
- method: :post,
225
- data: { testid: "source-health-action-full_fetch" }
226
- },
227
- {
228
- key: :health_check,
229
- label: "Run Health Check",
230
- description: "Sends a single request to confirm the feed is reachable without modifying stored items.",
231
- path: helpers.source_health_check_path(source),
232
- method: :post,
233
- data: { testid: "source-health-action-health_check" }
234
- }
235
- ]
236
- when "auto_paused"
237
- [
238
- {
239
- key: :reset,
240
- label: "Reset to Active Status",
241
- description: "Clears the pause window, failure counters, and schedules the next fetch using the configured interval.",
242
- path: helpers.source_health_reset_path(source),
243
- method: :post,
244
- data: { testid: "source-health-action-reset" }
245
- }
246
- ]
247
- else
248
- []
249
- end
250
- end
251
-
252
- def interactive_health_status?(source, override: nil)
253
- return false if override.present?
254
-
255
- %w[critical declining auto_paused].include?(source&.health_status.presence)
256
- end
257
-
258
- def table_sort_direction(search_object, attribute)
259
- return unless search_object.respond_to?(:sorts)
260
-
261
- sort = search_object.sorts.detect { |s| s && s.name == attribute.to_s }
262
- sort&.dir
263
- end
264
-
265
- def table_sort_arrow(search_object, attribute, default: nil)
266
- direction = table_sort_direction(search_object, attribute) || default&.to_s
267
-
268
- case direction
269
- when "asc"
270
- "▲"
271
- when "desc"
272
- "▼"
273
- else
274
- "↕"
275
- end
276
- end
277
-
278
- def table_sort_aria(search_object, attribute)
279
- direction = table_sort_direction(search_object, attribute)
280
-
281
- case direction
282
- when "asc"
283
- "ascending"
284
- when "desc"
285
- "descending"
286
- else
287
- "none"
288
- end
289
- end
290
-
291
- def table_sort_link(search_object, attribute, label, frame:, default_order:, secondary: [], html_options: {})
292
- sort_targets = [ attribute, *Array(secondary) ]
293
- options = {
294
- default_order: default_order,
295
- hide_indicator: true
296
- }.merge(html_options)
297
-
298
- options[:data] = (options[:data] || {}).merge(turbo_frame: frame)
299
- options[:data][:turbo_action] ||= "advance"
300
-
301
- sort_link(search_object, attribute, sort_targets, options) do
302
- tag.span(label, class: "inline-flex items-center gap-1")
303
- end
304
- end
305
-
306
198
  def formatted_setting_value(value)
307
199
  case value
308
200
  when TrueClass
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SourceMonitor
4
+ module HealthBadgeHelper
5
+ def source_health_badge(source, override: nil)
6
+ return override if override.present?
7
+
8
+ status = source&.health_status.presence || "healthy"
9
+
10
+ mapping = {
11
+ "healthy" => { label: "Healthy", classes: "bg-green-100 text-green-700", show_spinner: false },
12
+ "warning" => { label: "Needs Attention", classes: "bg-amber-100 text-amber-700", show_spinner: false },
13
+ "critical" => { label: "Failing", classes: "bg-rose-100 text-rose-700", show_spinner: false },
14
+ "declining" => { label: "Declining", classes: "bg-orange-100 text-orange-700", show_spinner: false },
15
+ "improving" => { label: "Improving", classes: "bg-sky-100 text-sky-700", show_spinner: false },
16
+ "auto_paused" => { label: "Auto-Paused", classes: "bg-amber-100 text-amber-700", show_spinner: false },
17
+ "unknown" => { label: "Unknown", classes: "bg-slate-100 text-slate-600", show_spinner: false }
18
+ }
19
+
20
+ mapping.fetch(status) { mapping.fetch("unknown") }.merge(status: status)
21
+ end
22
+
23
+ def source_health_actions(source)
24
+ status = source&.health_status.presence || "healthy"
25
+ helpers = SourceMonitor::Engine.routes.url_helpers
26
+
27
+ case status
28
+ when "critical", "declining"
29
+ [
30
+ {
31
+ key: :full_fetch,
32
+ label: "Queue Full Fetch",
33
+ description: "Runs the full fetch pipeline immediately and updates items if the feed responds.",
34
+ path: helpers.source_fetch_path(source),
35
+ method: :post,
36
+ data: { testid: "source-health-action-full_fetch" }
37
+ },
38
+ {
39
+ key: :health_check,
40
+ label: "Run Health Check",
41
+ description: "Sends a single request to confirm the feed is reachable without modifying stored items.",
42
+ path: helpers.source_health_check_path(source),
43
+ method: :post,
44
+ data: { testid: "source-health-action-health_check" }
45
+ }
46
+ ]
47
+ when "auto_paused"
48
+ [
49
+ {
50
+ key: :reset,
51
+ label: "Reset to Active Status",
52
+ description: "Clears the pause window, failure counters, and schedules the next fetch using the configured interval.",
53
+ path: helpers.source_health_reset_path(source),
54
+ method: :post,
55
+ data: { testid: "source-health-action-reset" }
56
+ }
57
+ ]
58
+ else
59
+ []
60
+ end
61
+ end
62
+
63
+ def interactive_health_status?(source, override: nil)
64
+ return false if override.present?
65
+
66
+ %w[critical declining auto_paused].include?(source&.health_status.presence)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SourceMonitor
4
+ module TableSortHelper
5
+ def table_sort_direction(search_object, attribute)
6
+ return unless search_object.respond_to?(:sorts)
7
+
8
+ sort = search_object.sorts.detect { |s| s && s.name == attribute.to_s }
9
+ sort&.dir
10
+ end
11
+
12
+ def table_sort_arrow(search_object, attribute, default: nil)
13
+ direction = table_sort_direction(search_object, attribute) || default&.to_s
14
+
15
+ case direction
16
+ when "asc"
17
+ "▲"
18
+ when "desc"
19
+ "▼"
20
+ else
21
+ "↕"
22
+ end
23
+ end
24
+
25
+ def table_sort_aria(search_object, attribute)
26
+ direction = table_sort_direction(search_object, attribute)
27
+
28
+ case direction
29
+ when "asc"
30
+ "ascending"
31
+ when "desc"
32
+ "descending"
33
+ else
34
+ "none"
35
+ end
36
+ end
37
+
38
+ def table_sort_link(search_object, attribute, label, frame:, default_order:, secondary: [], html_options: {})
39
+ sort_targets = [ attribute, *Array(secondary) ]
40
+ options = {
41
+ default_order: default_order,
42
+ hide_indicator: true
43
+ }.merge(html_options)
44
+
45
+ options[:data] = (options[:data] || {}).merge(turbo_frame: frame)
46
+ options[:data][:turbo_action] ||= "advance"
47
+
48
+ sort_link(search_object, attribute, sort_targets, options) do
49
+ tag.span(label, class: "inline-flex items-center gap-1")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SourceMonitor
2
4
  parent_job = defined?(::ApplicationJob) ? ::ApplicationJob : ActiveJob::Base
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SourceMonitor
2
4
  class ApplicationRecord < ActiveRecord::Base
3
5
  self.abstract_class = true
@@ -2,8 +2,6 @@
2
2
 
3
3
  module SourceMonitor
4
4
  class LogEntry < ApplicationRecord
5
- self.table_name = "sourcemon_log_entries"
6
-
7
5
  delegated_type :loggable, types: %w[SourceMonitor::FetchLog SourceMonitor::ScrapeLog SourceMonitor::HealthCheckLog]
8
6
 
9
7
  belongs_to :source, class_name: "SourceMonitor::Source", inverse_of: :log_entries