solid_cache_dashboard 0.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +121 -0
  3. data/Rakefile +10 -0
  4. data/app/assets/javascripts/solid_cache_dashboard/alpine.js +5 -0
  5. data/app/assets/javascripts/solid_cache_dashboard/application.js +60 -0
  6. data/app/assets/stylesheets/solid_cache_dashboard/application.css +1468 -0
  7. data/app/assets/stylesheets/solid_cache_dashboard/tailwind.css +625 -0
  8. data/app/controllers/solid_cache_dashboard/appearance_controller.rb +9 -0
  9. data/app/controllers/solid_cache_dashboard/application_controller.rb +12 -0
  10. data/app/controllers/solid_cache_dashboard/cache_entries_controller.rb +37 -0
  11. data/app/controllers/solid_cache_dashboard/cache_events_controller.rb +9 -0
  12. data/app/controllers/solid_cache_dashboard/dashboard_controller.rb +69 -0
  13. data/app/controllers/solid_cache_dashboard/stats_controller.rb +19 -0
  14. data/app/helpers/solid_cache_dashboard/application_helper.rb +20 -0
  15. data/app/views/layouts/solid_cache_dashboard/application.html.erb +28 -0
  16. data/app/views/solid_cache_dashboard/application/_flash_messages.html.erb +10 -0
  17. data/app/views/solid_cache_dashboard/application/_footer.html.erb +12 -0
  18. data/app/views/solid_cache_dashboard/application/_navbar.html.erb +32 -0
  19. data/app/views/solid_cache_dashboard/cache_entries/index.html.erb +136 -0
  20. data/app/views/solid_cache_dashboard/cache_entries/show.html.erb +118 -0
  21. data/app/views/solid_cache_dashboard/cache_events/index.html.erb +152 -0
  22. data/app/views/solid_cache_dashboard/dashboard/index.html.erb +163 -0
  23. data/app/views/solid_cache_dashboard/stats/index.html.erb +302 -0
  24. data/config/routes.rb +17 -0
  25. data/lib/generators/solid_cache_dashboard/install/install_generator.rb +17 -0
  26. data/lib/generators/solid_cache_dashboard/install/templates/create_solid_cache_dashboard_events.rb +16 -0
  27. data/lib/solid_cache_dashboard/cache_entry.rb +18 -0
  28. data/lib/solid_cache_dashboard/cache_event.rb +22 -0
  29. data/lib/solid_cache_dashboard/configuration.rb +17 -0
  30. data/lib/solid_cache_dashboard/decorators/cache_entries_decorator.rb +27 -0
  31. data/lib/solid_cache_dashboard/decorators/cache_entry_decorator.rb +59 -0
  32. data/lib/solid_cache_dashboard/decorators/cache_event_decorator.rb +72 -0
  33. data/lib/solid_cache_dashboard/decorators/cache_events_decorator.rb +44 -0
  34. data/lib/solid_cache_dashboard/engine.rb +19 -0
  35. data/lib/solid_cache_dashboard/instrumentation.rb +58 -0
  36. data/lib/solid_cache_dashboard/models/cache_event.rb +51 -0
  37. data/lib/solid_cache_dashboard/version.rb +5 -0
  38. data/lib/solid_cache_dashboard.rb +39 -0
  39. data/package-lock.json +1040 -0
  40. data/package.json +16 -0
  41. metadata +125 -0
@@ -0,0 +1,625 @@
1
+ @import 'tailwindcss';
2
+
3
+ @plugin 'tailwindcss-animate';
4
+ @plugin '@tailwindcss/forms' {
5
+ strategy: 'class';
6
+ }
7
+
8
+ @custom-variant dark (&:is(.dark *));
9
+
10
+ @theme {
11
+ --color-border: hsl(var(--border));
12
+ --color-input: hsl(var(--input));
13
+ --color-ring: hsl(var(--ring));
14
+ --color-background: hsl(var(--background));
15
+ --color-foreground: hsl(var(--foreground));
16
+
17
+ --color-primary: hsl(var(--primary));
18
+ --color-primary-foreground: hsl(var(--primary-foreground));
19
+
20
+ --color-secondary: hsl(var(--secondary));
21
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
22
+
23
+ --color-destructive: hsl(var(--destructive));
24
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
25
+
26
+ --color-muted: hsl(var(--muted));
27
+ --color-muted-foreground: hsl(var(--muted-foreground));
28
+
29
+ --color-accent: hsl(var(--accent));
30
+ --color-accent-foreground: hsl(var(--accent-foreground));
31
+
32
+ --color-popover: hsl(var(--popover));
33
+ --color-popover-foreground: hsl(var(--popover-foreground));
34
+
35
+ --color-card: hsl(var(--card));
36
+ --color-card-foreground: hsl(var(--card-foreground));
37
+
38
+ --radius-lg: var(--radius);
39
+ --radius-md: calc(var(--radius) - 2px);
40
+ --radius-sm: calc(var(--radius) - 4px);
41
+
42
+ --animate-accordion-down: accordion-down 0.2s ease-out;
43
+ --animate-accordion-up: accordion-up 0.2s ease-out;
44
+
45
+ @keyframes accordion-down {
46
+ from {
47
+ height: 0;
48
+ }
49
+ to {
50
+ height: var(--radix-accordion-content-height);
51
+ }
52
+ }
53
+ @keyframes accordion-up {
54
+ from {
55
+ height: var(--radix-accordion-content-height);
56
+ }
57
+ to {
58
+ height: 0;
59
+ }
60
+ }
61
+ }
62
+
63
+ @utility container {
64
+ margin-inline: auto;
65
+ padding-inline: 2rem;
66
+ @media (width >= --theme(--breakpoint-sm)) {
67
+ max-width: none;
68
+ }
69
+ @media (width >= 1400px) {
70
+ max-width: 1400px;
71
+ }
72
+ }
73
+
74
+ /*
75
+ The default border color has changed to `currentColor` in Tailwind CSS v4,
76
+ so we've added these compatibility styles to make sure everything still
77
+ looks the same as it did with Tailwind CSS v3.
78
+
79
+ If we ever want to remove these styles, we need to add an explicit border
80
+ color utility to any element that depends on these defaults.
81
+ */
82
+ @layer base {
83
+ *,
84
+ ::after,
85
+ ::before,
86
+ ::backdrop,
87
+ ::file-selector-button {
88
+ border-color: var(--color-gray-200, currentColor);
89
+ }
90
+ }
91
+
92
+ @utility label {
93
+ /*
94
+ Label
95
+ */
96
+ @apply text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70;
97
+ }
98
+
99
+ @utility select {
100
+ /*
101
+ Select
102
+ */
103
+ @apply form-select w-48 border border-input bg-white dark:bg-black text-foreground rounded-md h-10 px-3 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
104
+ }
105
+
106
+ @utility badge {
107
+ /*
108
+ Badge
109
+ */
110
+ @apply border inline-flex items-center gap-x-1.5 rounded-md px-1.5 py-0.5 text-sm/5 font-medium sm:text-xs/5 forced-colors:outline;
111
+ }
112
+
113
+ @utility badge-primary {
114
+ @apply border-transparent bg-primary text-primary-foreground hover:bg-primary/80;
115
+ }
116
+
117
+ @utility badge-secondary {
118
+ @apply border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80;
119
+ }
120
+
121
+ @utility badge-destructive {
122
+ @apply border-transparent bg-destructive/15 text-destructive dark:bg-destructive/10 dark:text-destructive-foreground;
123
+ }
124
+
125
+ @utility badge-outline {
126
+ @apply text-foreground;
127
+ }
128
+
129
+ @utility badge-red {
130
+ @apply border-transparent bg-red-500/15 text-red-700 dark:bg-red-500/10 dark:text-red-400;
131
+ }
132
+
133
+ @utility badge-orange {
134
+ @apply border-transparent bg-orange-500/15 text-orange-700 dark:bg-orange-500/10 dark:text-orange-400;
135
+ }
136
+
137
+ @utility badge-amber {
138
+ @apply border-transparent bg-amber-400/20 text-amber-700 dark:bg-amber-400/10 dark:text-amber-400;
139
+ }
140
+
141
+ @utility badge-yellow {
142
+ @apply border-transparent bg-yellow-400/20 text-yellow-700 dark:bg-yellow-400/10 dark:text-yellow-300;
143
+ }
144
+
145
+ @utility badge-lime {
146
+ @apply border-transparent bg-lime-400/20 text-lime-700 dark:bg-lime-400/10 dark:text-lime-300;
147
+ }
148
+
149
+ @utility badge-green {
150
+ @apply border-transparent bg-green-500/15 text-green-700 dark:bg-green-500/10 dark:text-green-400;
151
+ }
152
+
153
+ @utility badge-emerald {
154
+ @apply border-transparent bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-400;
155
+ }
156
+
157
+ @utility badge-teal {
158
+ @apply border-transparent bg-teal-500/15 text-teal-700 dark:bg-teal-500/10 dark:text-teal-300;
159
+ }
160
+
161
+ @utility badge-cyan {
162
+ @apply border-transparent bg-cyan-400/20 text-cyan-700 dark:bg-cyan-400/10 dark:text-cyan-300;
163
+ }
164
+
165
+ @utility badge-sky {
166
+ @apply border-transparent bg-sky-500/15 text-sky-700 dark:bg-sky-500/10 dark:text-sky-300;
167
+ }
168
+
169
+ @utility badge-blue {
170
+ @apply border-transparent bg-blue-500/15 text-blue-700 dark:text-blue-400;
171
+ }
172
+
173
+ @utility badge-indigo {
174
+ @apply border-transparent bg-indigo-500/15 text-indigo-700 dark:text-indigo-400;
175
+ }
176
+
177
+ @utility badge-violet {
178
+ @apply border-transparent bg-violet-500/15 text-violet-700 dark:text-violet-400;
179
+ }
180
+
181
+ @utility badge-purple {
182
+ @apply border-transparent bg-purple-500/15 text-purple-700 dark:text-purple-400;
183
+ }
184
+
185
+ @utility badge-fuchsia {
186
+ @apply border-transparent bg-fuchsia-400/15 text-fuchsia-700 dark:bg-fuchsia-400/10 dark:text-fuchsia-400;
187
+ }
188
+
189
+ @utility badge-pink {
190
+ @apply border-transparent bg-pink-400/15 text-pink-700 dark:bg-pink-400/10 dark:text-pink-400;
191
+ }
192
+
193
+ @utility badge-rose {
194
+ @apply border-transparent bg-rose-400/15 text-rose-700 dark:bg-rose-400/10 dark:text-rose-400;
195
+ }
196
+
197
+ @utility badge-zinc {
198
+ @apply border-transparent bg-zinc-600/7.5 text-zinc-700 dark:bg-white/5 dark:text-zinc-400;
199
+ }
200
+
201
+ @utility circle {
202
+ /*
203
+ Circle
204
+ */
205
+ @apply size-2 inline-flex items-center justify-center rounded-full;
206
+ }
207
+
208
+ @utility circle-primary {
209
+ @apply bg-primary;
210
+ }
211
+
212
+ @utility circle-secondary {
213
+ @apply bg-secondary;
214
+ }
215
+
216
+ @utility circle-destructive {
217
+ @apply bg-destructive;
218
+ }
219
+
220
+ @utility circle-outline {
221
+ @apply border border-current bg-background;
222
+ }
223
+
224
+ @utility circle-red {
225
+ @apply bg-red-500;
226
+ }
227
+
228
+ @utility circle-orange {
229
+ @apply bg-orange-500;
230
+ }
231
+
232
+ @utility circle-amber {
233
+ @apply bg-amber-400;
234
+ }
235
+
236
+ @utility circle-yellow {
237
+ @apply bg-yellow-400;
238
+ }
239
+
240
+ @utility circle-lime {
241
+ @apply bg-lime-400;
242
+ }
243
+
244
+ @utility circle-green {
245
+ @apply bg-green-500;
246
+ }
247
+
248
+ @utility circle-emerald {
249
+ @apply bg-emerald-500;
250
+ }
251
+
252
+ @utility circle-teal {
253
+ @apply bg-teal-500;
254
+ }
255
+
256
+ @utility circle-cyan {
257
+ @apply bg-cyan-400;
258
+ }
259
+
260
+ @utility circle-sky {
261
+ @apply bg-sky-500;
262
+ }
263
+
264
+ @utility circle-blue {
265
+ @apply bg-blue-500;
266
+ }
267
+
268
+ @utility circle-indigo {
269
+ @apply bg-indigo-500;
270
+ }
271
+
272
+ @utility circle-violet {
273
+ @apply bg-violet-500;
274
+ }
275
+
276
+ @utility circle-purple {
277
+ @apply bg-purple-500;
278
+ }
279
+
280
+ @utility circle-fuchsia {
281
+ @apply bg-fuchsia-400;
282
+ }
283
+
284
+ @utility circle-pink {
285
+ @apply bg-pink-400;
286
+ }
287
+
288
+ @utility circle-rose {
289
+ @apply bg-rose-400;
290
+ }
291
+
292
+ @utility circle-zinc {
293
+ @apply bg-zinc-400;
294
+ }
295
+
296
+ @utility alert {
297
+ /*
298
+ Alert
299
+ */
300
+ @apply relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground;
301
+ }
302
+
303
+ @utility alert-default {
304
+ @apply bg-background text-foreground;
305
+ }
306
+
307
+ @utility alert-destructive {
308
+ @apply border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive;
309
+ }
310
+
311
+ @utility alert-red {
312
+ @apply border-red-500/50 text-red-700 dark:border-red-500 dark:text-red-300 [&>svg]:text-red-500;
313
+ }
314
+
315
+ @utility alert-green {
316
+ @apply border-green-500/50 text-green-700 dark:border-green-500 dark:text-green-300 [&>svg]:text-green-500;
317
+ }
318
+
319
+ @utility alert-yellow {
320
+ @apply border-yellow-500/50 text-yellow-700 dark:border-yellow-500 dark:text-yellow-300 [&>svg]:text-yellow-500;
321
+ }
322
+
323
+ @utility alert-blue {
324
+ @apply border-blue-500/50 text-blue-700 dark:border-blue-500 dark:text-blue-300 [&>svg]:text-blue-500;
325
+ }
326
+
327
+ @utility alert-purple {
328
+ @apply border-purple-500/50 text-purple-700 dark:border-purple-500 dark:text-purple-300 [&>svg]:text-purple-500;
329
+ }
330
+
331
+ @utility alert-pink {
332
+ @apply border-pink-500/50 text-pink-700 dark:border-pink-500 dark:text-pink-300 [&>svg]:text-pink-500;
333
+ }
334
+
335
+ @utility alert-title {
336
+ @apply mb-1 font-medium leading-none tracking-tight;
337
+ }
338
+
339
+ @utility alert-description {
340
+ @apply text-sm [&_p]:leading-relaxed;
341
+ }
342
+
343
+ @utility btn {
344
+ /*
345
+ Button
346
+ */
347
+ @apply inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50;
348
+ }
349
+
350
+ @utility btn-default {
351
+ @apply bg-primary text-primary-foreground hover:bg-primary/90;
352
+ }
353
+
354
+ @utility btn-destructive {
355
+ @apply bg-destructive text-destructive-foreground hover:bg-destructive/90;
356
+ }
357
+
358
+ @utility btn-outline {
359
+ @apply border border-input bg-background hover:bg-accent hover:text-accent-foreground;
360
+ }
361
+
362
+ @utility btn-secondary {
363
+ @apply bg-secondary text-secondary-foreground hover:bg-secondary/80;
364
+ }
365
+
366
+ @utility btn-ghost {
367
+ @apply hover:bg-accent hover:text-accent-foreground;
368
+ }
369
+
370
+ @utility btn-link {
371
+ @apply text-primary underline-offset-4 hover:underline;
372
+ }
373
+
374
+ @utility btn-xs {
375
+ @apply h-7 rounded-md px-2 gap-1;
376
+ }
377
+
378
+ @utility btn-sm {
379
+ @apply h-9 rounded-md px-3 gap-1.5;
380
+ }
381
+
382
+ @utility btn-md {
383
+ @apply h-10 px-4 py-2 gap-1.5;
384
+ }
385
+
386
+ @utility btn-lg {
387
+ @apply h-11 rounded-md px-8 gap-2;
388
+ }
389
+
390
+ @utility btn-icon {
391
+ @apply h-10 w-10;
392
+ }
393
+
394
+ @utility info-line {
395
+ /*
396
+ Info Line
397
+ */
398
+ @apply flex items-center gap-4;
399
+ }
400
+
401
+ @utility info-line-label {
402
+ @apply text-zinc-500 whitespace-nowrap;
403
+ }
404
+
405
+ @utility info-line-separator {
406
+ @apply h-px flex-1 bg-zinc-950/10 dark:border-white/10 translate-y-px;
407
+ }
408
+
409
+ @utility info-line-value {
410
+ @apply font-medium text-right text-zinc-950 dark:text-white;
411
+ }
412
+
413
+ @utility card {
414
+ /*
415
+ Card
416
+ */
417
+ @apply rounded-lg border bg-card text-card-foreground shadow-xs;
418
+ }
419
+
420
+ @utility card-header {
421
+ @apply flex flex-col space-y-1.5 p-6;
422
+ }
423
+
424
+ @utility card-title {
425
+ @apply text-2xl font-semibold leading-none tracking-tight;
426
+ }
427
+
428
+ @utility card-description {
429
+ @apply text-sm text-muted-foreground;
430
+ }
431
+
432
+ @utility card-content {
433
+ @apply p-6 pt-0;
434
+ }
435
+
436
+ @utility card-footer {
437
+ @apply flex items-center p-6 pt-0;
438
+ }
439
+
440
+ @utility navbar {
441
+ /*
442
+ Navbar
443
+ */
444
+ @apply flex items-center gap-4 bg-background py-4;
445
+ }
446
+
447
+ @utility navbar-section {
448
+ @apply flex gap-1.5;
449
+ }
450
+
451
+ @utility navbar-item {
452
+ @apply inline-flex items-center rounded-md justify-center px-3 py-2 text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2;
453
+ }
454
+
455
+ @utility navbar-item-default {
456
+ @apply text-foreground hover:bg-accent hover:text-accent-foreground;
457
+ }
458
+
459
+ @utility navbar-item-current {
460
+ @apply bg-primary text-primary-foreground;
461
+ }
462
+
463
+ @utility table-wrapper {
464
+ /*
465
+ Table
466
+ */
467
+ @apply relative w-full overflow-auto;
468
+ }
469
+
470
+ @utility table {
471
+ @apply w-full caption-bottom text-sm;
472
+ }
473
+
474
+ @utility table-header {
475
+ @apply [&_tr]:border-b;
476
+ }
477
+
478
+ @utility table-body {
479
+ @apply [&_tr:last-child]:border-0;
480
+ }
481
+
482
+ @utility table-footer {
483
+ @apply border-t bg-muted/50 font-medium last:[&>tr]:border-b-0;
484
+ }
485
+
486
+ @utility table-row {
487
+ @apply border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted;
488
+ }
489
+
490
+ @utility table-head {
491
+ @apply h-12 px-4 text-left align-middle font-medium text-muted-foreground whitespace-nowrap [&:has([role=checkbox])]:pr-0;
492
+ }
493
+
494
+ @utility table-cell {
495
+ @apply p-4 align-middle [&:has([role=checkbox])]:pr-0;
496
+ }
497
+
498
+ @utility table-caption {
499
+ @apply mt-4 text-sm text-muted-foreground;
500
+ }
501
+
502
+ @utility pagination {
503
+ /*
504
+ Pagination
505
+ */
506
+ @apply flex justify-center;
507
+ }
508
+
509
+ @utility pagination-content {
510
+ @apply flex flex-row items-center gap-1;
511
+ }
512
+
513
+ @utility pagination-item {
514
+ @apply inline-block;
515
+ }
516
+
517
+ @utility pagination-link {
518
+ @apply inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50;
519
+ }
520
+
521
+ @utility pagination-link-active {
522
+ @apply border border-input bg-background hover:bg-accent hover:text-accent-foreground;
523
+ }
524
+
525
+ @utility pagination-link-inactive {
526
+ @apply hover:bg-accent hover:text-accent-foreground;
527
+ }
528
+
529
+ @utility pagination-link-icon {
530
+ @apply h-9 w-9;
531
+ }
532
+
533
+ @utility pagination-link-default {
534
+ @apply h-10 px-4 py-2;
535
+ }
536
+
537
+ @utility pagination-previous {
538
+ @apply h-10 px-4 py-2 gap-1;
539
+ @apply pl-2.5;
540
+ }
541
+
542
+ @utility pagination-next {
543
+ @apply h-10 px-4 py-2 gap-1;
544
+ @apply pr-2.5;
545
+ }
546
+
547
+ @utility pagination-ellipsis {
548
+ @apply flex h-9 w-9 items-center justify-center;
549
+ }
550
+
551
+ @layer base {
552
+ :root {
553
+ --background: 0 0% 98%;
554
+ --foreground: 240 10% 3.9%;
555
+ --card: 0 0% 100%;
556
+ --card-foreground: 240 10% 3.9%;
557
+ --popover: 0 0% 100%;
558
+ --popover-foreground: 240 10% 3.9%;
559
+ --primary: 240 5.9% 10%;
560
+ --primary-foreground: 0 0% 98%;
561
+ --secondary: 240 4.8% 95.9%;
562
+ --secondary-foreground: 240 5.9% 10%;
563
+ --muted: 240 4.8% 95.9%;
564
+ --muted-foreground: 240 3.8% 46.1%;
565
+ --accent: 240 4.8% 93.8%;
566
+ --accent-foreground: 240 5.9% 10%;
567
+ --destructive: 0 84.2% 60.2%;
568
+ --destructive-foreground: 0 0% 98%;
569
+ --border: 240 5.9% 90%;
570
+ --input: 240 5.9% 90%;
571
+ --ring: 240 5.9% 10%;
572
+ --radius: 0.65rem;
573
+ --chart-1: 12 76% 61%;
574
+ --chart-2: 173 58% 39%;
575
+ --chart-3: 197 37% 24%;
576
+ --chart-4: 43 74% 66%;
577
+ --chart-5: 27 87% 67%;
578
+ }
579
+
580
+ .dark {
581
+ --background: 240 10% 5.4%;
582
+ --foreground: 0 0% 92%;
583
+ --card: 240 10% 3.9%;
584
+ --card-foreground: 0 0% 92%;
585
+ --popover: 240 10% 3.9%;
586
+ --popover-foreground: 0 0% 98%;
587
+ --primary: 0 0% 95%;
588
+ --primary-foreground: 240 5.9% 10%;
589
+ --secondary: 240 3.7% 15.9%;
590
+ --secondary-foreground: 0 0% 98%;
591
+ --muted: 240 3.7% 15.9%;
592
+ --muted-foreground: 240 5% 64.9%;
593
+ --accent: 240 3.7% 15.9%;
594
+ --accent-foreground: 0 0% 98%;
595
+ --destructive: 0 62.8% 30.6%;
596
+ --destructive-foreground: 0 0% 98%;
597
+ --border: 240 3.7% 11%;
598
+ --input: 240 3.7% 15.9%;
599
+ --ring: 240 4.9% 83.9%;
600
+ --chart-1: 220 70% 50%;
601
+ --chart-2: 160 60% 45%;
602
+ --chart-3: 30 80% 55%;
603
+ --chart-4: 280 65% 60%;
604
+ --chart-5: 340 75% 55%;
605
+ }
606
+ }
607
+
608
+ @layer base {
609
+ * {
610
+ @apply border-zinc-300;
611
+ }
612
+
613
+ body {
614
+ @apply bg-background text-foreground;
615
+ font-feature-settings: "rlig" 1, "calt" 1;
616
+ }
617
+
618
+ [data-href] {
619
+ @apply cursor-pointer;
620
+ }
621
+
622
+ .link {
623
+ @apply underline hover:opacity-75;
624
+ }
625
+ }
@@ -0,0 +1,9 @@
1
+ module SolidCacheDashboard
2
+ class AppearanceController < ApplicationController
3
+ def toggle
4
+ cookies[:solid_cache_dashboard_dark_mode] = dark_mode? ? "false" : "true"
5
+
6
+ redirect_back(fallback_location: root_path)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module SolidCacheDashboard
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+
5
+ helper SolidCacheDashboard::ApplicationHelper
6
+
7
+ def dark_mode?
8
+ cookies[:solid_cache_dashboard_dark_mode] == "true"
9
+ end
10
+ helper_method :dark_mode?
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ module SolidCacheDashboard
2
+ class CacheEntriesController < ApplicationController
3
+ def index
4
+ @cache_entries = SolidCacheDashboard.decorate(
5
+ SolidCache::Entry.order(created_at: :desc)#.page(params[:page]).per(25)
6
+ )
7
+ end
8
+
9
+ def show
10
+ @cache_entry = SolidCacheDashboard.decorate(
11
+ SolidCache::Entry.find_by_key_hash(params[:id].to_i)
12
+ )
13
+
14
+ unless @cache_entry
15
+ redirect_to cache_entries_path, alert: "Cache entry not found"
16
+ return
17
+ end
18
+ end
19
+
20
+ def delete
21
+ cache_entry = SolidCache::Entry.find_by_key_hash(params[:id].to_i)
22
+
23
+ if cache_entry
24
+ cache_entry.delete
25
+ redirect_to cache_entries_path, notice: "Cache entry deleted"
26
+ else
27
+ redirect_to cache_entries_path, alert: "Cache entry not found"
28
+ end
29
+ end
30
+
31
+ def clear_all
32
+ SolidCache::Entry.delete_all
33
+ SolidCacheDashboard::CacheEvent.delete_all if defined?(SolidCacheDashboard::CacheEvent)
34
+ redirect_to cache_entries_path, notice: "All cache entries and statistics have been reset"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,9 @@
1
+ module SolidCacheDashboard
2
+ class CacheEventsController < ApplicationController
3
+ def index
4
+ @cache_events = SolidCacheDashboard.decorate(
5
+ SolidCacheDashboard::CacheEvent.order(created_at: :desc)#.page(params[:page]).per(25)
6
+ )
7
+ end
8
+ end
9
+ end