solidstats 2.0.0 → 3.0.0.beta.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.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -63
  3. data/README.md +27 -33
  4. data/Rakefile +3 -3
  5. data/app/assets/stylesheets/solidstats/application.css +1 -6
  6. data/app/assets/stylesheets/solidstats/dashboard.css +48 -0
  7. data/app/controllers/solidstats/dashboard_controller.rb +81 -62
  8. data/app/controllers/solidstats/logs_controller.rb +72 -0
  9. data/app/controllers/solidstats/performance_controller.rb +25 -0
  10. data/app/controllers/solidstats/productivity_controller.rb +39 -0
  11. data/app/controllers/solidstats/quality_controller.rb +152 -0
  12. data/app/controllers/solidstats/securities_controller.rb +30 -0
  13. data/app/helpers/solidstats/application_helper.rb +124 -11
  14. data/app/helpers/solidstats/performance_helper.rb +87 -0
  15. data/app/helpers/solidstats/productivity_helper.rb +38 -0
  16. data/app/services/solidstats/bundler_audit_service.rb +206 -0
  17. data/app/services/solidstats/coverage_compass_service.rb +335 -0
  18. data/app/services/solidstats/load_lens_service.rb +454 -0
  19. data/app/services/solidstats/log_size_monitor_service.rb +207 -76
  20. data/app/services/solidstats/my_todo_service.rb +242 -0
  21. data/app/services/solidstats/style_patrol_service.rb +319 -0
  22. data/app/views/layouts/solidstats/application.html.erb +8 -2
  23. data/app/views/layouts/solidstats/dashboard.html.erb +84 -0
  24. data/app/views/solidstats/dashboard/dashboard.html.erb +39 -0
  25. data/app/views/solidstats/logs/logs_size.html.erb +409 -0
  26. data/app/views/solidstats/performance/load_lens.html.erb +158 -0
  27. data/app/views/solidstats/productivity/_todo_list.html.erb +49 -0
  28. data/app/views/solidstats/productivity/my_todos.html.erb +84 -0
  29. data/app/views/solidstats/quality/coverage_compass.html.erb +420 -0
  30. data/app/views/solidstats/quality/style_patrol.html.erb +463 -0
  31. data/app/views/solidstats/securities/bundler_audit.html.erb +345 -0
  32. data/app/views/solidstats/shared/_dashboard_card.html.erb +160 -0
  33. data/app/views/solidstats/shared/_quick_actions.html.erb +26 -0
  34. data/config/routes.rb +32 -7
  35. data/lib/generators/solidstats/install/install_generator.rb +28 -2
  36. data/lib/generators/solidstats/install/templates/README +7 -0
  37. data/lib/solidstats/engine.rb +9 -114
  38. data/lib/solidstats/version.rb +1 -1
  39. data/lib/solidstats.rb +2 -299
  40. data/lib/tasks/solidstats_install.rake +2 -122
  41. data/lib/tasks/solidstats_performance.rake +84 -0
  42. metadata +32 -103
  43. data/app/assets/javascripts/solidstats/application.js +0 -257
  44. data/app/assets/javascripts/solidstats/dashboard.js +0 -225
  45. data/app/assets/javascripts/solidstats/gem_metadata.js +0 -554
  46. data/app/assets/stylesheets/solidstats/components/action_button.css +0 -99
  47. data/app/assets/stylesheets/solidstats/components/dashboard.css +0 -151
  48. data/app/assets/stylesheets/solidstats/components/dashboard_header.css +0 -93
  49. data/app/assets/stylesheets/solidstats/components/dashboard_layout.css +0 -97
  50. data/app/assets/stylesheets/solidstats/components/gem_metadata.css +0 -1403
  51. data/app/assets/stylesheets/solidstats/components/navigation.css +0 -80
  52. data/app/assets/stylesheets/solidstats/components/quick_navigation.css +0 -54
  53. data/app/assets/stylesheets/solidstats/components/security.css +0 -332
  54. data/app/assets/stylesheets/solidstats/components/status_badge.css +0 -58
  55. data/app/assets/stylesheets/solidstats/components/summary_card.css +0 -66
  56. data/app/assets/stylesheets/solidstats/components/tab_navigation.css +0 -95
  57. data/app/components/solidstats/base_component.rb +0 -88
  58. data/app/components/solidstats/code_quality/code_quality_section_component.html.erb +0 -0
  59. data/app/components/solidstats/code_quality/code_quality_section_component.rb +0 -0
  60. data/app/components/solidstats/code_quality/section_component.html.erb +0 -45
  61. data/app/components/solidstats/code_quality/section_component.rb +0 -34
  62. data/app/components/solidstats/dashboard_header_component.html.erb +0 -39
  63. data/app/components/solidstats/dashboard_header_component.rb +0 -33
  64. data/app/components/solidstats/previews/action_button_component_preview/button_vs_link.html.erb +0 -6
  65. data/app/components/solidstats/previews/action_button_component_preview/sizes.html.erb +0 -6
  66. data/app/components/solidstats/previews/action_button_component_preview/variants.html.erb +0 -6
  67. data/app/components/solidstats/previews/action_button_component_preview/with_icons.html.erb +0 -6
  68. data/app/components/solidstats/previews/action_button_component_preview.rb +0 -64
  69. data/app/components/solidstats/previews/navigation_component_preview.rb +0 -74
  70. data/app/components/solidstats/previews/stats_overview_component_preview.rb +0 -100
  71. data/app/components/solidstats/previews/status_badge_component_preview/sizes.html.erb +0 -6
  72. data/app/components/solidstats/previews/status_badge_component_preview/statuses.html.erb +0 -6
  73. data/app/components/solidstats/previews/status_badge_component_preview/with_icons.html.erb +0 -6
  74. data/app/components/solidstats/previews/status_badge_component_preview.rb +0 -49
  75. data/app/components/solidstats/previews/summary_card_component_preview/clickable.html.erb +0 -9
  76. data/app/components/solidstats/previews/summary_card_component_preview/dashboard_layout.html.erb +0 -9
  77. data/app/components/solidstats/previews/summary_card_component_preview/statuses.html.erb +0 -6
  78. data/app/components/solidstats/previews/summary_card_component_preview/value_formats.html.erb +0 -6
  79. data/app/components/solidstats/previews/summary_card_component_preview.rb +0 -67
  80. data/app/components/solidstats/quick_navigation_component.html.erb +0 -8
  81. data/app/components/solidstats/quick_navigation_component.rb +0 -21
  82. data/app/components/solidstats/security/gem_impact_analysis_component.html.erb +0 -44
  83. data/app/components/solidstats/security/gem_impact_analysis_component.rb +0 -45
  84. data/app/components/solidstats/security/overview_component.html.erb +0 -21
  85. data/app/components/solidstats/security/overview_component.rb +0 -104
  86. data/app/components/solidstats/security/section_component.html.erb +0 -26
  87. data/app/components/solidstats/security/section_component.rb +0 -52
  88. data/app/components/solidstats/security/timeline_component.html.erb +0 -39
  89. data/app/components/solidstats/security/timeline_component.rb +0 -43
  90. data/app/components/solidstats/tasks_section_component.html.erb +0 -17
  91. data/app/components/solidstats/tasks_section_component.rb +0 -22
  92. data/app/components/solidstats/ui/action_button_component.html.erb +0 -6
  93. data/app/components/solidstats/ui/action_button_component.rb +0 -71
  94. data/app/components/solidstats/ui/dashboard_layout_component.html.erb +0 -19
  95. data/app/components/solidstats/ui/dashboard_layout_component.rb +0 -85
  96. data/app/components/solidstats/ui/navigation_component.html.erb +0 -34
  97. data/app/components/solidstats/ui/navigation_component.rb +0 -72
  98. data/app/components/solidstats/ui/stats_overview_component.html.erb +0 -14
  99. data/app/components/solidstats/ui/stats_overview_component.rb +0 -78
  100. data/app/components/solidstats/ui/status_badge_component.html.erb +0 -6
  101. data/app/components/solidstats/ui/status_badge_component.rb +0 -42
  102. data/app/components/solidstats/ui/summary_card_component.html.erb +0 -12
  103. data/app/components/solidstats/ui/summary_card_component.rb +0 -63
  104. data/app/components/solidstats/ui/tab_navigation_component.html.erb +0 -22
  105. data/app/components/solidstats/ui/tab_navigation_component.rb +0 -79
  106. data/app/controllers/solidstats/gem_metadata_controller.rb +0 -12
  107. data/app/services/solidstats/audit_service.rb +0 -56
  108. data/app/services/solidstats/data_collector_service.rb +0 -83
  109. data/app/services/solidstats/gem_metadata/fetcher_service.rb +0 -136
  110. data/app/services/solidstats/todo_service.rb +0 -114
  111. data/app/views/solidstats/dashboard/_log_monitor.html.erb +0 -759
  112. data/app/views/solidstats/dashboard/_todos.html.erb +0 -151
  113. data/app/views/solidstats/dashboard/audit/_additional_styles.css +0 -22
  114. data/app/views/solidstats/dashboard/audit/_audit_badge.html.erb +0 -5
  115. data/app/views/solidstats/dashboard/audit/_audit_details.html.erb +0 -495
  116. data/app/views/solidstats/dashboard/audit/_audit_summary.html.erb +0 -26
  117. data/app/views/solidstats/dashboard/audit/_no_vulnerabilities.html.erb +0 -3
  118. data/app/views/solidstats/dashboard/audit/_security_audit.html.erb +0 -14
  119. data/app/views/solidstats/dashboard/audit/_vulnerabilities_table.html.erb +0 -1120
  120. data/app/views/solidstats/dashboard/audit/_vulnerability_details.html.erb +0 -63
  121. data/app/views/solidstats/dashboard/index.html.erb +0 -81
  122. data/app/views/solidstats/gem_metadata/_panel.html.erb +0 -419
  123. data/lib/generators/solidstats/feature/feature_generator.rb +0 -170
  124. data/lib/generators/solidstats/feature/templates/component.html.erb +0 -84
  125. data/lib/generators/solidstats/feature/templates/component.rb.erb +0 -103
  126. data/lib/generators/solidstats/feature/templates/component.scss +0 -243
  127. data/lib/generators/solidstats/feature/templates/component_test.rb.erb +0 -183
  128. data/lib/generators/solidstats/feature/templates/controller.rb.erb +0 -44
  129. data/lib/generators/solidstats/feature/templates/controller_test.rb.erb +0 -111
  130. data/lib/generators/solidstats/feature/templates/detail_view.html.erb +0 -755
  131. data/lib/generators/solidstats/feature/templates/preview.rb.erb +0 -107
  132. data/lib/generators/solidstats/feature/templates/service.rb.erb +0 -132
  133. data/lib/generators/solidstats/feature/templates/service_test.rb.erb +0 -109
  134. data/lib/generators/solidstats/install_generator.rb +0 -109
  135. data/lib/generators/solidstats/templates/initializer.rb +0 -112
  136. data/lib/solidstats/asset_compatibility.rb +0 -238
  137. data/lib/solidstats/asset_manifest.rb +0 -205
  138. data/lib/tasks/solidstats_tasks.rake +0 -4
@@ -1,759 +0,0 @@
1
- <%
2
- # Convert status symbol to CSS class and display text
3
- status_class = case @log_data[:status]
4
- when :ok then "status-ok"
5
- when :warning then "status-warning"
6
- when :danger then "status-danger"
7
- else ""
8
- end
9
-
10
- status_text = case @log_data[:status]
11
- when :ok then "✅ OK: Log files are within acceptable limits"
12
- when :warning then "⚠️ Warning: Log files are getting large"
13
- when :danger then "❌ Danger: Log files are too large"
14
- else "Unknown status"
15
- end
16
-
17
- # Calculate meter fill percentage (capped at 100%)
18
- fill_percentage = [(@log_data[:total_size_mb] / 50.0) * 100, 100].min
19
-
20
- # Set color based on status
21
- fill_color = case @log_data[:status]
22
- when :ok then "#28a745"
23
- when :warning then "#ffc107"
24
- when :danger then "#dc3545"
25
- else "#6c757d"
26
- end
27
- %>
28
-
29
- <div class="log-monitor-card">
30
- <div class="log-header">
31
- <div>
32
- <h3><span class="icon">📊</span> Log Size Monitor</h3>
33
- <p class="log-path"><%= @log_data[:log_dir_path] %></p>
34
- </div>
35
- <div class="log-actions">
36
- <button id="truncate-all-logs-btn" class="action-button truncate-button">
37
- <span class="action-icon">✂️</span> Truncate All Logs
38
- </button>
39
- </div>
40
- </div>
41
-
42
- <div class="log-content">
43
- <div class="log-status">
44
- <div class="log-indicator <%= status_class %>"></div>
45
- <div class="log-status-text"><%= status_text %></div>
46
- </div>
47
-
48
- <div class="log-size-container">
49
- <div class="log-size-label">Total Size:</div>
50
- <div class="log-size-value"><%= @log_data[:total_size_mb] %> MB</div>
51
- <div class="log-files-count">(<%= @log_data[:logs_count] %> log files)</div>
52
- </div>
53
-
54
- <div class="log-size-meter">
55
- <div class="meter-bg"></div>
56
- <div class="meter-fill" style="width: <%= fill_percentage %>%; background-color: <%= fill_color %>;"></div>
57
- <div class="meter-markers">
58
- <div class="marker" style="left: 0%">0</div>
59
- <div class="marker warning-marker" style="left: 50%">25 MB</div>
60
- <div class="marker danger-marker" style="left: 100%">50+ MB</div>
61
- </div>
62
- </div>
63
- </div>
64
-
65
- <div class="log-files-table">
66
- <h4>Individual Log Files</h4>
67
- <table>
68
- <thead>
69
- <tr>
70
- <th>File Name</th>
71
- <th>Size</th>
72
- <th>Last Modified</th>
73
- <th>Status</th>
74
- <th>Actions</th>
75
- </tr>
76
- </thead>
77
- <tbody>
78
- <% @log_data[:log_files].each do |log_file| %>
79
- <%
80
- file_status_class = case log_file[:status]
81
- when :ok then "status-ok"
82
- when :warning then "status-warning"
83
- when :danger then "status-danger"
84
- else ""
85
- end
86
- %>
87
- <tr class="<%= file_status_class %>">
88
- <td class="filename"><%= log_file[:filename] %></td>
89
- <td class="size"><%= log_file[:size_mb] %> MB</td>
90
- <td class="modified"><%= log_file[:last_modified].strftime("%b %d, %Y %H:%M") %></td>
91
- <td class="status">
92
- <% if log_file[:status] == :ok %>
93
- <span class="status-icon">✅</span>
94
- <% elsif log_file[:status] == :warning %>
95
- <span class="status-icon">⚠️</span>
96
- <% else %>
97
- <span class="status-icon">❌</span>
98
- <% end %>
99
- </td>
100
- <td class="actions">
101
- <button class="truncate-file-btn" data-filename="<%= log_file[:filename] %>">
102
- <span class="action-icon">✂️</span> Truncate
103
- </button>
104
- </td>
105
- </tr>
106
- <% end %>
107
- </tbody>
108
- </table>
109
- </div>
110
-
111
- <div class="log-recommendations">
112
- <h4>Recommendations</h4>
113
- <ul>
114
- <% if @log_data[:status] == :danger %>
115
- <li><strong>Immediate action required:</strong> Your log files exceed 50MB in total. Consider truncating them now.</li>
116
- <% elsif @log_data[:status] == :warning %>
117
- <li><strong>Monitor closely:</strong> Your log files exceed 25MB in total. Consider truncating them soon.</li>
118
- <% end %>
119
- <li>Configure log rotation to automatically manage log file sizes</li>
120
- <li>For production environments, consider using a log management service</li>
121
- </ul>
122
- </div>
123
- </div>
124
-
125
- <style>
126
- .log-monitor-card {
127
- background-color: #fff;
128
- border-radius: 8px;
129
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
130
- overflow: hidden;
131
- margin-top: 1rem;
132
- margin-bottom: 1.5rem;
133
- }
134
-
135
- .log-header {
136
- padding: 1rem;
137
- display: flex;
138
- justify-content: space-between;
139
- align-items: flex-start;
140
- border-bottom: 1px solid #eee;
141
- }
142
-
143
- .log-header h3 {
144
- font-size: 1.2rem;
145
- margin: 0 0 0.5rem;
146
- font-weight: 600;
147
- display: flex;
148
- align-items: center;
149
- gap: 0.5rem;
150
- }
151
-
152
- .log-path {
153
- font-family: monospace;
154
- font-size: 0.8rem;
155
- color: #666;
156
- margin: 0;
157
- word-break: break-all;
158
- }
159
-
160
- .log-actions {
161
- flex-shrink: 0;
162
- }
163
-
164
- .truncate-button {
165
- display: inline-flex;
166
- align-items: center;
167
- padding: 0.5rem 1rem;
168
- background-color: #f8f9fa;
169
- border: 1px solid #dee2e6;
170
- color: #333;
171
- border-radius: 4px;
172
- font-size: 0.9rem;
173
- cursor: pointer;
174
- transition: all 0.2s;
175
- }
176
-
177
- .truncate-button:hover {
178
- background-color: #e9ecef;
179
- }
180
-
181
- .log-content {
182
- padding: 1rem;
183
- }
184
-
185
- .log-status {
186
- display: flex;
187
- align-items: center;
188
- gap: 0.75rem;
189
- margin-bottom: 1rem;
190
- }
191
-
192
- .log-indicator {
193
- width: 12px;
194
- height: 12px;
195
- border-radius: 50%;
196
- background-color: #6c757d;
197
- }
198
-
199
- .log-indicator.status-ok {
200
- background-color: #28a745;
201
- }
202
-
203
- .log-indicator.status-warning {
204
- background-color: #ffc107;
205
- }
206
-
207
- .log-indicator.status-danger {
208
- background-color: #dc3545;
209
- }
210
-
211
- .log-status-text {
212
- font-weight: 500;
213
- }
214
-
215
- .log-size-container {
216
- display: flex;
217
- align-items: center;
218
- gap: 0.5rem;
219
- margin-bottom: 0.75rem;
220
- }
221
-
222
- .log-size-label {
223
- font-size: 0.9rem;
224
- color: #495057;
225
- }
226
-
227
- .log-size-value {
228
- font-weight: 600;
229
- font-size: 1.1rem;
230
- }
231
-
232
- .log-files-count {
233
- font-size: 0.9rem;
234
- color: #6c757d;
235
- }
236
-
237
- .log-size-meter {
238
- position: relative;
239
- height: 30px;
240
- background-color: #f8f9fa;
241
- border-radius: 4px;
242
- overflow: hidden;
243
- margin-top: 1rem;
244
- margin-bottom: 1rem;
245
- }
246
-
247
- .meter-bg {
248
- position: absolute;
249
- top: 0;
250
- left: 0;
251
- width: 100%;
252
- height: 100%;
253
- background: linear-gradient(to right, #28a745 0%, #28a745 50%, #ffc107 50%, #ffc107 75%, #dc3545 75%, #dc3545 100%);
254
- opacity: 0.15;
255
- }
256
-
257
- .meter-fill {
258
- position: absolute;
259
- top: 0;
260
- left: 0;
261
- height: 100%;
262
- transition: width 0.5s;
263
- }
264
-
265
- .meter-markers {
266
- position: absolute;
267
- bottom: 0;
268
- left: 0;
269
- width: 100%;
270
- height: 100%;
271
- display: flex;
272
- align-items: flex-end;
273
- padding-bottom: 0.25rem;
274
- }
275
-
276
- .marker {
277
- position: absolute;
278
- font-size: 0.7rem;
279
- transform: translateX(-50%);
280
- padding: 2px 4px;
281
- color: #495057;
282
- }
283
-
284
- .warning-marker {
285
- color: #856404;
286
- }
287
-
288
- .danger-marker {
289
- color: #721c24;
290
- }
291
-
292
- .log-files-table {
293
- padding: 1rem;
294
- border-top: 1px solid #eee;
295
- }
296
-
297
- .log-files-table h4 {
298
- font-size: 1rem;
299
- margin-top: 0;
300
- margin-bottom: 0.75rem;
301
- }
302
-
303
- .log-files-table table {
304
- width: 100%;
305
- border-collapse: collapse;
306
- font-size: 0.9rem;
307
- }
308
-
309
- .log-files-table th,
310
- .log-files-table td {
311
- padding: 0.5rem;
312
- text-align: left;
313
- border-bottom: 1px solid #eee;
314
- }
315
-
316
- .log-files-table th {
317
- font-weight: 600;
318
- color: #495057;
319
- }
320
-
321
- .log-files-table tr:last-child td {
322
- border-bottom: none;
323
- }
324
-
325
- .log-files-table .filename {
326
- font-family: monospace;
327
- max-width: 200px;
328
- overflow: hidden;
329
- text-overflow: ellipsis;
330
- white-space: nowrap;
331
- }
332
-
333
- .log-files-table .status {
334
- text-align: center;
335
- }
336
-
337
- .log-files-table .actions {
338
- text-align: right;
339
- }
340
-
341
- .log-files-table .truncate-file-btn {
342
- padding: 0.25rem 0.5rem;
343
- font-size: 0.8rem;
344
- background-color: #f8f9fa;
345
- border: 1px solid #dee2e6;
346
- border-radius: 4px;
347
- cursor: pointer;
348
- display: inline-flex;
349
- align-items: center;
350
- gap: 0.25rem;
351
- }
352
-
353
- .log-files-table .truncate-file-btn:hover {
354
- background-color: #e9ecef;
355
- }
356
-
357
- .log-files-table tr.status-danger {
358
- background-color: rgba(220, 53, 69, 0.05);
359
- }
360
-
361
- .log-files-table tr.status-warning {
362
- background-color: rgba(255, 193, 7, 0.05);
363
- }
364
-
365
- .log-recommendations {
366
- padding: 1rem;
367
- background-color: #f8f9fa;
368
- border-top: 1px solid #eee;
369
- }
370
-
371
- .log-recommendations h4 {
372
- font-size: 1rem;
373
- margin-top: 0;
374
- margin-bottom: 0.5rem;
375
- }
376
-
377
- .log-recommendations ul {
378
- margin-bottom: 0;
379
- padding-left: 1.5rem;
380
- }
381
-
382
- .log-recommendations li {
383
- margin-bottom: 0.3rem;
384
- font-size: 0.9rem;
385
- }
386
-
387
- .log-recommendations li:last-child {
388
- margin-bottom: 0;
389
- }
390
- </style>
391
-
392
- <script>
393
- document.addEventListener('DOMContentLoaded', function() {
394
- // Truncate all logs
395
- const truncateAllLogsBtn = document.getElementById('truncate-all-logs-btn');
396
- if (truncateAllLogsBtn) {
397
- truncateAllLogsBtn.addEventListener('click', function() {
398
- // Confirm before truncating
399
- if (!confirm('Are you sure you want to truncate ALL log files? This action cannot be undone.')) {
400
- return;
401
- }
402
-
403
- truncateLog(null, this);
404
- });
405
- }
406
-
407
- // Individual file truncate buttons
408
- document.querySelectorAll('.truncate-file-btn').forEach(function(button) {
409
- button.addEventListener('click', function() {
410
- const filename = this.getAttribute('data-filename');
411
-
412
- // Confirm before truncating
413
- if (!confirm(`Are you sure you want to truncate log file: ${filename}? This action cannot be undone.`)) {
414
- return;
415
- }
416
-
417
- truncateLog(filename, this);
418
- });
419
- });
420
-
421
- function truncateLog(filename, button) {
422
- const originalText = button.innerHTML;
423
- button.innerHTML = '<span class="action-icon">⏳</span> Truncating...';
424
- button.disabled = true;
425
-
426
- // Strip .log extension from filename if present (controller will add it back)
427
- let urlFilename = filename;
428
- if (urlFilename && urlFilename.endsWith('.log')) {
429
- urlFilename = urlFilename.substring(0, urlFilename.length - 4);
430
- }
431
-
432
- const url = urlFilename ?
433
- '<%= solidstats.truncate_log_path %>/' + encodeURIComponent(urlFilename) :
434
- '<%= solidstats.truncate_log_path %>';
435
-
436
- fetch(url, {
437
- method: 'POST',
438
- headers: {
439
- 'Accept': 'application/json',
440
- 'X-Requested-With': 'XMLHttpRequest',
441
- 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
442
- },
443
- credentials: 'same-origin'
444
- })
445
- .then(response => response.json())
446
- .then(data => {
447
- if (data.success) {
448
- showNotification(data.message, 'success');
449
- // Reload the page to see updated log sizes
450
- window.location.reload();
451
- } else {
452
- showNotification(data.message, 'error');
453
- // Reset button state
454
- button.innerHTML = originalText;
455
- button.disabled = false;
456
- }
457
- })
458
- .catch(error => {
459
- console.error('Error truncating log file:', error);
460
- showNotification('Failed to truncate log file', 'error');
461
-
462
- // Reset button state
463
- button.innerHTML = originalText;
464
- button.disabled = false;
465
- });
466
- }
467
- });
468
-
469
- // Notification function if not already defined
470
- if (typeof showNotification !== 'function') {
471
- function showNotification(message, type) {
472
- // Create notification element
473
- const notification = document.createElement('div');
474
- notification.className = `toast-notification ${type}`;
475
- notification.textContent = message;
476
-
477
- // Add to body
478
- document.body.appendChild(notification);
479
-
480
- // Show notification
481
- setTimeout(() => {
482
- notification.classList.add('visible');
483
- }, 10);
484
-
485
- // Hide and remove notification
486
- setTimeout(() => {
487
- notification.classList.remove('visible');
488
- setTimeout(() => {
489
- notification.remove();
490
- }, 300);
491
- }, 5000);
492
- }
493
- }
494
- </script>
495
-
496
- <style>
497
- .log-monitor-card {
498
- background-color: #fff;
499
- border-radius: 8px;
500
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
501
- overflow: hidden;
502
- margin-top: 1rem;
503
- margin-bottom: 1.5rem;
504
- }
505
-
506
- .log-header {
507
- padding: 1rem;
508
- display: flex;
509
- justify-content: space-between;
510
- align-items: flex-start;
511
- border-bottom: 1px solid #eee;
512
- }
513
-
514
- .log-header h3 {
515
- font-size: 1.2rem;
516
- margin: 0 0 0.5rem;
517
- font-weight: 600;
518
- display: flex;
519
- align-items: center;
520
- gap: 0.5rem;
521
- }
522
-
523
- .log-path {
524
- font-family: monospace;
525
- font-size: 0.8rem;
526
- color: #666;
527
- margin: 0;
528
- word-break: break-all;
529
- }
530
-
531
- .log-actions {
532
- flex-shrink: 0;
533
- }
534
-
535
- .truncate-button {
536
- display: inline-flex;
537
- align-items: center;
538
- padding: 0.5rem 1rem;
539
- background-color: #f8f9fa;
540
- border: 1px solid #dee2e6;
541
- color: #333;
542
- border-radius: 4px;
543
- font-size: 0.9rem;
544
- cursor: pointer;
545
- transition: all 0.2s;
546
- }
547
-
548
- .truncate-button:hover {
549
- background-color: #e9ecef;
550
- }
551
-
552
- .log-content {
553
- padding: 1rem;
554
- }
555
-
556
- .log-status {
557
- display: flex;
558
- align-items: center;
559
- gap: 0.75rem;
560
- margin-bottom: 1rem;
561
- }
562
-
563
- .log-indicator {
564
- width: 12px;
565
- height: 12px;
566
- border-radius: 50%;
567
- background-color: #6c757d;
568
- }
569
-
570
- .log-indicator.status-ok {
571
- background-color: #28a745;
572
- }
573
-
574
- .log-indicator.status-warning {
575
- background-color: #ffc107;
576
- }
577
-
578
- .log-indicator.status-danger {
579
- background-color: #dc3545;
580
- }
581
-
582
- .log-status-text {
583
- font-weight: 500;
584
- }
585
-
586
- .log-size-container {
587
- display: flex;
588
- align-items: center;
589
- gap: 0.5rem;
590
- margin-bottom: 0.75rem;
591
- }
592
-
593
- .log-size-label {
594
- font-size: 0.9rem;
595
- color: #495057;
596
- }
597
-
598
- .log-size-value {
599
- font-weight: 600;
600
- font-size: 1.1rem;
601
- }
602
-
603
- .log-size-meter {
604
- position: relative;
605
- height: 30px;
606
- background-color: #f8f9fa;
607
- border-radius: 4px;
608
- overflow: hidden;
609
- margin-top: 1rem;
610
- margin-bottom: 1rem;
611
- }
612
-
613
- .meter-bg {
614
- position: absolute;
615
- top: 0;
616
- left: 0;
617
- width: 100%;
618
- height: 100%;
619
- background: linear-gradient(to right, #28a745 0%, #28a745 50%, #ffc107 50%, #ffc107 75%, #dc3545 75%, #dc3545 100%);
620
- opacity: 0.15;
621
- }
622
-
623
- .meter-fill {
624
- position: absolute;
625
- top: 0;
626
- left: 0;
627
- height: 100%;
628
- transition: width 0.5s;
629
- }
630
-
631
- .meter-markers {
632
- position: absolute;
633
- bottom: 0;
634
- left: 0;
635
- width: 100%;
636
- height: 100%;
637
- display: flex;
638
- align-items: flex-end;
639
- padding-bottom: 0.25rem;
640
- }
641
-
642
- .marker {
643
- position: absolute;
644
- font-size: 0.7rem;
645
- transform: translateX(-50%);
646
- padding: 2px 4px;
647
- color: #495057;
648
- }
649
-
650
- .warning-marker {
651
- color: #856404;
652
- }
653
-
654
- .danger-marker {
655
- color: #721c24;
656
- }
657
-
658
- .log-recommendations {
659
- padding: 1rem;
660
- background-color: #f8f9fa;
661
- border-top: 1px solid #eee;
662
- }
663
-
664
- .log-recommendations h4 {
665
- font-size: 1rem;
666
- margin-top: 0;
667
- margin-bottom: 0.5rem;
668
- }
669
-
670
- .log-recommendations ul {
671
- margin-bottom: 0;
672
- padding-left: 1.5rem;
673
- }
674
-
675
- .log-recommendations li {
676
- margin-bottom: 0.3rem;
677
- font-size: 0.9rem;
678
- }
679
-
680
- .log-recommendations li:last-child {
681
- margin-bottom: 0;
682
- }
683
- </style>
684
-
685
- <script>
686
- document.addEventListener('DOMContentLoaded', function() {
687
- const truncateButton = document.getElementById('truncate-log-btn');
688
- if (truncateButton) {
689
- truncateButton.addEventListener('click', function() {
690
- // Confirm before truncating
691
- if (!confirm('Are you sure you want to truncate the log file? This action cannot be undone.')) {
692
- return;
693
- }
694
-
695
- const button = this;
696
- const originalText = button.innerHTML;
697
- button.innerHTML = '<span class="action-icon">⏳</span> Truncating...';
698
- button.disabled = true;
699
-
700
- fetch('<%= solidstats.truncate_log_path %>', {
701
- method: 'POST',
702
- headers: {
703
- 'Accept': 'application/json',
704
- 'X-Requested-With': 'XMLHttpRequest',
705
- 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
706
- },
707
- credentials: 'same-origin'
708
- })
709
- .then(response => response.json())
710
- .then(data => {
711
- if (data.success) {
712
- showNotification(data.message, 'success');
713
- // Reload the page to see updated log size
714
- window.location.reload();
715
- } else {
716
- showNotification(data.message, 'error');
717
- // Reset button state
718
- button.innerHTML = originalText;
719
- button.disabled = false;
720
- }
721
- })
722
- .catch(error => {
723
- console.error('Error truncating log file:', error);
724
- showNotification('Failed to truncate log file', 'error');
725
-
726
- // Reset button state
727
- button.innerHTML = originalText;
728
- button.disabled = false;
729
- });
730
- });
731
- }
732
- });
733
-
734
- // Notification function if not already defined
735
- if (typeof showNotification !== 'function') {
736
- function showNotification(message, type) {
737
- // Create notification element
738
- const notification = document.createElement('div');
739
- notification.className = `toast-notification ${type}`;
740
- notification.textContent = message;
741
-
742
- // Add to body
743
- document.body.appendChild(notification);
744
-
745
- // Show notification
746
- setTimeout(() => {
747
- notification.classList.add('visible');
748
- }, 10);
749
-
750
- // Hide and remove notification
751
- setTimeout(() => {
752
- notification.classList.remove('visible');
753
- setTimeout(() => {
754
- notification.remove();
755
- }, 300);
756
- }, 5000);
757
- }
758
- }
759
- </script>