railwatch 0.6.1 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/app/frontend/components/app-content.tsx +26 -0
- data/app/frontend/components/app-logo-icon.tsx +23 -0
- data/app/frontend/components/app-logo.tsx +14 -0
- data/app/frontend/components/app-shell.tsx +38 -0
- data/app/frontend/components/app-sidebar-header.tsx +54 -0
- data/app/frontend/components/app-sidebar.tsx +94 -0
- data/app/frontend/components/app-wordmark.tsx +29 -0
- data/app/frontend/components/breadcrumbs.tsx +46 -0
- data/app/frontend/components/icon.tsx +16 -0
- data/app/frontend/components/input-error.tsx +18 -0
- data/app/frontend/components/nav-footer.tsx +46 -0
- data/app/frontend/components/nav-main.tsx +41 -0
- data/app/frontend/components/nav-user.tsx +50 -0
- data/app/frontend/components/railwatch/chart-hover.tsx +34 -0
- data/app/frontend/components/railwatch/chart-panel.tsx +170 -0
- data/app/frontend/components/railwatch/code.tsx +28 -0
- data/app/frontend/components/railwatch/command-palette.tsx +132 -0
- data/app/frontend/components/railwatch/copy-block.tsx +52 -0
- data/app/frontend/components/railwatch/copy-id.tsx +49 -0
- data/app/frontend/components/railwatch/cursor-load-more.tsx +39 -0
- data/app/frontend/components/railwatch/data-table.tsx +195 -0
- data/app/frontend/components/railwatch/digit-roll.tsx +312 -0
- data/app/frontend/components/railwatch/empty-state.tsx +159 -0
- data/app/frontend/components/railwatch/env-nav.tsx +130 -0
- data/app/frontend/components/railwatch/env-switcher.tsx +145 -0
- data/app/frontend/components/railwatch/filter-bar.tsx +153 -0
- data/app/frontend/components/railwatch/flamegraph.tsx +324 -0
- data/app/frontend/components/railwatch/frames.tsx +295 -0
- data/app/frontend/components/railwatch/json-viewer.tsx +159 -0
- data/app/frontend/components/railwatch/live-dot.tsx +78 -0
- data/app/frontend/components/railwatch/live-toggle.tsx +76 -0
- data/app/frontend/components/railwatch/metric-chart.tsx +112 -0
- data/app/frontend/components/railwatch/mobile-page-switcher.tsx +89 -0
- data/app/frontend/components/railwatch/onboarding.tsx +91 -0
- data/app/frontend/components/railwatch/origin-identity.tsx +84 -0
- data/app/frontend/components/railwatch/page-header.tsx +42 -0
- data/app/frontend/components/railwatch/percentile-picker.tsx +18 -0
- data/app/frontend/components/railwatch/relative-time.tsx +18 -0
- data/app/frontend/components/railwatch/saved-views.tsx +232 -0
- data/app/frontend/components/railwatch/segmented.tsx +64 -0
- data/app/frontend/components/railwatch/series-chart.tsx +400 -0
- data/app/frontend/components/railwatch/shortcuts-dialog.tsx +89 -0
- data/app/frontend/components/railwatch/signal-toast.tsx +121 -0
- data/app/frontend/components/railwatch/sort-header.tsx +37 -0
- data/app/frontend/components/railwatch/source-link.tsx +57 -0
- data/app/frontend/components/railwatch/sparkline-cell.tsx +14 -0
- data/app/frontend/components/railwatch/sql-block.tsx +116 -0
- data/app/frontend/components/railwatch/stat.tsx +173 -0
- data/app/frontend/components/railwatch/status-badge.tsx +79 -0
- data/app/frontend/components/railwatch/step-picker.tsx +57 -0
- data/app/frontend/components/railwatch/timeline.tsx +405 -0
- data/app/frontend/components/railwatch/utilisation-bar.tsx +44 -0
- data/app/frontend/components/railwatch/window-picker.tsx +147 -0
- data/app/frontend/components/ui/avatar.tsx +51 -0
- data/app/frontend/components/ui/badge.tsx +46 -0
- data/app/frontend/components/ui/breadcrumb.tsx +109 -0
- data/app/frontend/components/ui/button.tsx +60 -0
- data/app/frontend/components/ui/card.tsx +92 -0
- data/app/frontend/components/ui/chart.tsx +374 -0
- data/app/frontend/components/ui/checkbox.tsx +32 -0
- data/app/frontend/components/ui/collapsible.tsx +31 -0
- data/app/frontend/components/ui/command.tsx +182 -0
- data/app/frontend/components/ui/dialog.tsx +158 -0
- data/app/frontend/components/ui/dropdown-menu.tsx +255 -0
- data/app/frontend/components/ui/hover-card.tsx +42 -0
- data/app/frontend/components/ui/input.tsx +21 -0
- data/app/frontend/components/ui/label.tsx +24 -0
- data/app/frontend/components/ui/popover.tsx +87 -0
- data/app/frontend/components/ui/select.tsx +185 -0
- data/app/frontend/components/ui/separator.tsx +28 -0
- data/app/frontend/components/ui/sheet.tsx +137 -0
- data/app/frontend/components/ui/sidebar.tsx +726 -0
- data/app/frontend/components/ui/skeleton.tsx +13 -0
- data/app/frontend/components/ui/sonner.tsx +41 -0
- data/app/frontend/components/ui/table.tsx +114 -0
- data/app/frontend/components/ui/tabs.tsx +91 -0
- data/app/frontend/components/ui/textarea.tsx +18 -0
- data/app/frontend/components/ui/tooltip.tsx +61 -0
- data/app/frontend/components/user-info.tsx +32 -0
- data/app/frontend/components/user-menu-content.tsx +94 -0
- data/app/frontend/entrypoints/application.css +244 -0
- data/app/frontend/entrypoints/inertia.tsx +95 -0
- data/app/frontend/fonts/CommitMono-Bold.woff2 +0 -0
- data/app/frontend/fonts/CommitMono-Regular.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Black.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Bold.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Medium.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Regular.woff2 +0 -0
- data/app/frontend/hooks/use-appearance.tsx +67 -0
- data/app/frontend/hooks/use-clipboard.ts +32 -0
- data/app/frontend/hooks/use-flash.tsx +23 -0
- data/app/frontend/hooks/use-hotkeys.ts +63 -0
- data/app/frontend/hooks/use-initials.tsx +15 -0
- data/app/frontend/hooks/use-live.ts +179 -0
- data/app/frontend/hooks/use-mobile-navigation.ts +8 -0
- data/app/frontend/hooks/use-mobile.ts +21 -0
- data/app/frontend/hooks/use-percentile.ts +24 -0
- data/app/frontend/hooks/use-reduced-motion.ts +25 -0
- data/app/frontend/hooks/use-row-nav.ts +106 -0
- data/app/frontend/hooks/use-step.ts +27 -0
- data/app/frontend/hooks/use-ticker.ts +12 -0
- data/app/frontend/hooks/use-window.ts +58 -0
- data/app/frontend/layouts/app/app-sidebar-layout.tsx +107 -0
- data/app/frontend/layouts/app-layout.tsx +21 -0
- data/app/frontend/layouts/env-layout.tsx +53 -0
- data/app/frontend/layouts/persistent-layout.tsx +18 -0
- data/app/frontend/lib/cable.ts +10 -0
- data/app/frontend/lib/env-pages.ts +236 -0
- data/app/frontend/lib/execution-path.ts +55 -0
- data/app/frontend/lib/explain.ts +50 -0
- data/app/frontend/lib/filter.ts +25 -0
- data/app/frontend/lib/flamegraph.ts +155 -0
- data/app/frontend/lib/format.ts +71 -0
- data/app/frontend/lib/keyboard.ts +18 -0
- data/app/frontend/lib/source-link.ts +217 -0
- data/app/frontend/lib/utils.ts +6 -0
- data/app/frontend/pages/alerts/index.tsx +171 -0
- data/app/frontend/pages/broadcasts/index.tsx +171 -0
- data/app/frontend/pages/cache_events/index.tsx +127 -0
- data/app/frontend/pages/commands/index.tsx +143 -0
- data/app/frontend/pages/deploys/index.tsx +94 -0
- data/app/frontend/pages/deploys/show.tsx +309 -0
- data/app/frontend/pages/deprecations/index.tsx +176 -0
- data/app/frontend/pages/exceptions/index.tsx +271 -0
- data/app/frontend/pages/executions/show.tsx +821 -0
- data/app/frontend/pages/issues/index.tsx +399 -0
- data/app/frontend/pages/issues/show.tsx +1367 -0
- data/app/frontend/pages/jobs/index.tsx +381 -0
- data/app/frontend/pages/jobs/klass.tsx +215 -0
- data/app/frontend/pages/llm_calls/index.tsx +664 -0
- data/app/frontend/pages/logs/index.tsx +303 -0
- data/app/frontend/pages/mails/index.tsx +218 -0
- data/app/frontend/pages/notifications/index.tsx +161 -0
- data/app/frontend/pages/outgoing_requests/index.tsx +309 -0
- data/app/frontend/pages/overview/show.tsx +333 -0
- data/app/frontend/pages/people/index.tsx +102 -0
- data/app/frontend/pages/people/show.tsx +149 -0
- data/app/frontend/pages/processes/index.tsx +335 -0
- data/app/frontend/pages/profiles/index.tsx +110 -0
- data/app/frontend/pages/profiles/show.tsx +105 -0
- data/app/frontend/pages/queries/index.tsx +492 -0
- data/app/frontend/pages/queries/show.tsx +276 -0
- data/app/frontend/pages/releases/index.tsx +190 -0
- data/app/frontend/pages/releases/release-health.tsx +68 -0
- data/app/frontend/pages/releases/release-path.ts +25 -0
- data/app/frontend/pages/releases/show.tsx +262 -0
- data/app/frontend/pages/requests/index.tsx +235 -0
- data/app/frontend/pages/requests/route.tsx +159 -0
- data/app/frontend/pages/scheduled_tasks/index.tsx +220 -0
- data/app/frontend/pages/spans/index.tsx +229 -0
- data/app/frontend/pages/spans/show.tsx +220 -0
- data/app/frontend/pages/storage_ops/index.tsx +150 -0
- data/app/frontend/pages/tenants/index.tsx +236 -0
- data/app/frontend/pages/tenants/show.tsx +477 -0
- data/app/frontend/pages/tenants/tenant-path.ts +26 -0
- data/app/frontend/pages/thresholds/index.tsx +414 -0
- data/app/frontend/pages/traces/show.tsx +208 -0
- data/app/frontend/pages/transactions/index.tsx +220 -0
- data/app/frontend/pages/view_renders/index.tsx +241 -0
- data/app/frontend/pages/visits/index.tsx +321 -0
- data/app/frontend/public/icon.png +0 -0
- data/app/frontend/public/icon.svg +5 -0
- data/app/frontend/routes/index.d.ts +2136 -0
- data/app/frontend/routes/index.js +2112 -0
- data/app/frontend/types/globals.d.ts +9 -0
- data/app/frontend/types/index.ts +288 -0
- data/app/frontend/types/vite-env.d.ts +9 -0
- data/lib/railwatch/version.rb +1 -1
- data/lib/railwatch.rb +8 -3
- data/public/railwatch/assets/app-layout-LvxN9xSS.js +41 -0
- data/public/railwatch/assets/application-Cc5v_Vk9.css +1 -0
- data/public/railwatch/assets/{arrow-up-CLQ-7heQ.js → arrow-up-DG01k9AL.js} +1 -1
- data/public/railwatch/assets/{braces-rSYydpLY.js → braces-C3w7pfxS.js} +1 -1
- data/public/railwatch/assets/{card-DPjFKfen.js → card-Dpwlr0uY.js} +1 -1
- data/public/railwatch/assets/{chart-DWh7l8yM.js → chart-DJHv3R7W.js} +1 -1
- data/public/railwatch/assets/{chart-hover-CfoZUY4J.js → chart-hover-CEH-DtXO.js} +1 -1
- data/public/railwatch/assets/{chart-panel-CC49WTQL.js → chart-panel-CUdIzJvk.js} +1 -1
- data/public/railwatch/assets/code-BRZprwun.js +1 -0
- data/public/railwatch/assets/copy-id-CwhGGiwF.js +1 -0
- data/public/railwatch/assets/cursor-load-more-uF1_955Q.js +1 -0
- data/public/railwatch/assets/data-table-DYi-N0hm.js +1 -0
- data/public/railwatch/assets/env-layout-HdcOaPPX.js +1 -0
- data/public/railwatch/assets/{execution-path-FAuIzOXB.js → execution-path-CElXXFO_.js} +1 -1
- data/public/railwatch/assets/filter-bar-DEv0G_34.js +1 -0
- data/public/railwatch/assets/{flamegraph-EaGkP2NT.js → flamegraph-SKD9yxW9.js} +2 -2
- data/public/railwatch/assets/frames-CUpyJQDy.js +1 -0
- data/public/railwatch/assets/index-2W-ppwap.js +1 -0
- data/public/railwatch/assets/index-74ocuU5d.js +1 -0
- data/public/railwatch/assets/{index-C8Cggnbw.js → index-B8NA62Lz.js} +2 -2
- data/public/railwatch/assets/index-BBCEkLqp.js +1 -0
- data/public/railwatch/assets/index-BDcglJzX.js +1 -0
- data/public/railwatch/assets/index-B_KFb9LS.js +1 -0
- data/public/railwatch/assets/index-BqK_VKom.js +1 -0
- data/public/railwatch/assets/index-BxCXBHP2.js +1 -0
- data/public/railwatch/assets/index-C1jc1OoH.js +1 -0
- data/public/railwatch/assets/index-C7zREldp.js +1 -0
- data/public/railwatch/assets/index-CEetm4oC.js +1 -0
- data/public/railwatch/assets/index-CIaZkokF.js +1 -0
- data/public/railwatch/assets/index-CNH85TZp.js +1 -0
- data/public/railwatch/assets/index-Ce4SB5AB.js +1 -0
- data/public/railwatch/assets/index-CiRMSYMn.js +1 -0
- data/public/railwatch/assets/index-CjxXgOs-.js +1 -0
- data/public/railwatch/assets/index-ClL-PYEV.js +1 -0
- data/public/railwatch/assets/index-CteZ6fop.js +1 -0
- data/public/railwatch/assets/index-CvqfEExO.js +1 -0
- data/public/railwatch/assets/index-CxTLT-Qh.js +1 -0
- data/public/railwatch/assets/index-DJd3OUSd.js +1 -0
- data/public/railwatch/assets/index-DPD-rLp6.js +1 -0
- data/public/railwatch/assets/index-DYK_dps4.js +1 -0
- data/public/railwatch/assets/index-DrayARrI.js +1 -0
- data/public/railwatch/assets/index-HRXGir-0.js +1 -0
- data/public/railwatch/assets/index-UJOUALr_.js +1 -0
- data/public/railwatch/assets/index-d-3J7gQ5.js +1 -0
- data/public/railwatch/assets/index-oQrvBpOm.js +1 -0
- data/public/railwatch/assets/inertia-FoqYZAk8.js +97 -0
- data/public/railwatch/assets/json-viewer-CxqMojEm.js +1 -0
- data/public/railwatch/assets/klass-DEF-Vat5.js +1 -0
- data/public/railwatch/assets/origin-identity-Y6gvfQVR.js +1 -0
- data/public/railwatch/assets/{percentile-picker-CeQgllxD.js → percentile-picker-E2aUdLxx.js} +1 -1
- data/public/railwatch/assets/relative-time-DcJbkKlN.js +1 -0
- data/public/railwatch/assets/{release-health-uP-GF3_V.js → release-health-C8WSCDKD.js} +1 -1
- data/public/railwatch/assets/route-qO5vX1p-.js +1 -0
- data/public/railwatch/assets/{segmented-BeIe4uqk.js → segmented-BWee8uc9.js} +1 -1
- data/public/railwatch/assets/select-G7rNBzv0.js +1 -0
- data/public/railwatch/assets/series-chart-C5nXIUc5.js +1 -0
- data/public/railwatch/assets/show-BEWisLQw.js +1 -0
- data/public/railwatch/assets/show-BEa9PGu1.js +2 -0
- data/public/railwatch/assets/{show-YsNpqbcI.js → show-BiT_Aloc.js} +3 -3
- data/public/railwatch/assets/show-BpCO49d3.js +1 -0
- data/public/railwatch/assets/show-CH7yxt7R.js +1 -0
- data/public/railwatch/assets/show-CTO8Lvd2.js +1 -0
- data/public/railwatch/assets/show-DnYsDMUt.js +2 -0
- data/public/railwatch/assets/show-DyzHM527.js +1 -0
- data/public/railwatch/assets/show-Nfpxs8su.js +1 -0
- data/public/railwatch/assets/show-ddjUMo9G.js +1 -0
- data/public/railwatch/assets/show-ksjbSzDH.js +1 -0
- data/public/railwatch/assets/{sort-header-mEJUM3Av.js → sort-header-uOq5VlrB.js} +1 -1
- data/public/railwatch/assets/{sparkline-cell-Dwg7awwh.js → sparkline-cell-DgGij0cu.js} +1 -1
- data/public/railwatch/assets/stat-BTzNKTm2.js +1 -0
- data/public/railwatch/assets/status-badge-BDkOXa-C.js +1 -0
- data/public/railwatch/assets/{tenant-path-CQoP-BeF.js → tenant-path-DU0ezKSU.js} +1 -1
- data/public/railwatch/assets/{use-clipboard-DNefo-ky.js → use-clipboard-DoENmlWY.js} +1 -1
- data/public/railwatch/assets/{use-live-DMTuhKfB.js → use-live-CE_fN5_6.js} +1 -1
- data/public/railwatch/manifest.json +612 -1591
- metadata +242 -117
- data/public/railwatch/assets/app-layout-Zc0v-hYh.js +0 -1
- data/public/railwatch/assets/app-wordmark-BA_60AVb.js +0 -1
- data/public/railwatch/assets/appearance-CcfP9tZ7.js +0 -1
- data/public/railwatch/assets/application-BrN3Sz94.css +0 -1
- data/public/railwatch/assets/auth-layout-C05gEBIQ.js +0 -1
- data/public/railwatch/assets/badge-DRae8XwK.js +0 -1
- data/public/railwatch/assets/checkbox-DPkLUiwM.js +0 -1
- data/public/railwatch/assets/code-CLmYS6FU.js +0 -1
- data/public/railwatch/assets/copy-DaQMJWoT.js +0 -1
- data/public/railwatch/assets/copy-block-CGcXxp8J.js +0 -1
- data/public/railwatch/assets/copy-id-vBYHQwxg.js +0 -1
- data/public/railwatch/assets/cursor-load-more-Ddwxe5dZ.js +0 -1
- data/public/railwatch/assets/data-table-CzKTEE-O.js +0 -1
- data/public/railwatch/assets/edit-B1kmWkzd.js +0 -8
- data/public/railwatch/assets/edit-D9cx4pbG.js +0 -1
- data/public/railwatch/assets/edit-yv6j9p-V.js +0 -1
- data/public/railwatch/assets/empty-state-CW4wclK_.js +0 -1
- data/public/railwatch/assets/env-layout-Kz7wks1x.js +0 -1
- data/public/railwatch/assets/filter-bar-CJDjWFib.js +0 -1
- data/public/railwatch/assets/frames-zZuIaNH9.js +0 -1
- data/public/railwatch/assets/google-sign-in-button-2_zgbgVy.js +0 -1
- data/public/railwatch/assets/index-B49SWz7K.js +0 -1
- data/public/railwatch/assets/index-BHlY4wKe.js +0 -1
- data/public/railwatch/assets/index-BZpPtyFY.js +0 -1
- data/public/railwatch/assets/index-BeVK6jCL.js +0 -1
- data/public/railwatch/assets/index-BfbSo01U.js +0 -1
- data/public/railwatch/assets/index-BfgncAv6.js +0 -1
- data/public/railwatch/assets/index-BhNszK1k.js +0 -1
- data/public/railwatch/assets/index-Bu01uWvw.js +0 -1
- data/public/railwatch/assets/index-C1s_hK3p.js +0 -1
- data/public/railwatch/assets/index-CBip6V4z.js +0 -1
- data/public/railwatch/assets/index-CMJGss5R.js +0 -1
- data/public/railwatch/assets/index-CRo3yK20.js +0 -1
- data/public/railwatch/assets/index-CWB_p2J8.js +0 -1
- data/public/railwatch/assets/index-CWHpndGc.js +0 -1
- data/public/railwatch/assets/index-Ca_S4Sc3.js +0 -1
- data/public/railwatch/assets/index-CanPDDOa.js +0 -1
- data/public/railwatch/assets/index-Cie90Yat.js +0 -1
- data/public/railwatch/assets/index-CiepQ_pR.js +0 -1
- data/public/railwatch/assets/index-Cm1uCIGN.js +0 -1
- data/public/railwatch/assets/index-CzitnnSC.js +0 -1
- data/public/railwatch/assets/index-DEUfClv3.js +0 -1
- data/public/railwatch/assets/index-DJKwo-mI.js +0 -1
- data/public/railwatch/assets/index-DK6y0YHp.js +0 -1
- data/public/railwatch/assets/index-DMNPpLH9.js +0 -1
- data/public/railwatch/assets/index-DZO1mSfX.js +0 -1
- data/public/railwatch/assets/index-Db5wj3M5.js +0 -1
- data/public/railwatch/assets/index-Dcy5WktB.js +0 -1
- data/public/railwatch/assets/index-DvG0-7Lx.js +0 -1
- data/public/railwatch/assets/index-Dvj1wuka.js +0 -1
- data/public/railwatch/assets/index-KyZX46qX.js +0 -1
- data/public/railwatch/assets/index-Ze-KP-sl.js +0 -1
- data/public/railwatch/assets/index-mhRbWLBM.js +0 -1
- data/public/railwatch/assets/index-x099JL5f.js +0 -1
- data/public/railwatch/assets/index-x28zb_nf.js +0 -1
- data/public/railwatch/assets/inertia-Cuyz2ZHO.js +0 -97
- data/public/railwatch/assets/input-error-hog6gGxg.js +0 -1
- data/public/railwatch/assets/json-viewer-DH2W9HXf.js +0 -1
- data/public/railwatch/assets/klass-DHbDelLk.js +0 -1
- data/public/railwatch/assets/label-DdCBgiUn.js +0 -1
- data/public/railwatch/assets/layout-Cueyl7c5.js +0 -1
- data/public/railwatch/assets/live-dot-BZgYTYdt.js +0 -41
- data/public/railwatch/assets/nav-BSSGObDZ.js +0 -1
- data/public/railwatch/assets/new-B8FSb8Bl.js +0 -1
- data/public/railwatch/assets/new-C39_v2Ll.js +0 -1
- data/public/railwatch/assets/new-DVOPwaC5.js +0 -1
- data/public/railwatch/assets/new-Dd40nvJR.js +0 -1
- data/public/railwatch/assets/new-SxnYe1SE.js +0 -1
- data/public/railwatch/assets/new-eP5vKD3Y.js +0 -1
- data/public/railwatch/assets/onboarding-CUpZl5KB.js +0 -1
- data/public/railwatch/assets/origin-identity-BYt2uiuo.js +0 -1
- data/public/railwatch/assets/relative-time-D5UbF4oO.js +0 -1
- data/public/railwatch/assets/route-DQAY8JEr.js +0 -1
- data/public/railwatch/assets/select-2R16457Z.js +0 -1
- data/public/railwatch/assets/separator-D5I0UCB5.js +0 -1
- data/public/railwatch/assets/series-chart-gnrzhmM6.js +0 -1
- data/public/railwatch/assets/show-2BkeNRUC.js +0 -2
- data/public/railwatch/assets/show-B0X1hRQH.js +0 -1
- data/public/railwatch/assets/show-BKUV5l5q.js +0 -1
- data/public/railwatch/assets/show-BQJD_CsF.js +0 -6
- data/public/railwatch/assets/show-BhmD6Sxp.js +0 -1
- data/public/railwatch/assets/show-C3KcnVo2.js +0 -1
- data/public/railwatch/assets/show-C95cHd06.js +0 -2
- data/public/railwatch/assets/show-CdB4uVQS.js +0 -1
- data/public/railwatch/assets/show-CoCqcVIp.js +0 -1
- data/public/railwatch/assets/show-D2LqjEsU.js +0 -1
- data/public/railwatch/assets/show-DNpnKyTh.js +0 -1
- data/public/railwatch/assets/show-DOlTxbig.js +0 -1
- data/public/railwatch/assets/show-DQCkttL8.js +0 -1
- data/public/railwatch/assets/show-DcxesipC.js +0 -1
- data/public/railwatch/assets/show-IGJoc_X0.js +0 -1
- data/public/railwatch/assets/show-qNV6H8SH.js +0 -2
- data/public/railwatch/assets/stat-ZtxGU8lE.js +0 -1
- data/public/railwatch/assets/status-badge-CH5P-Xkj.js +0 -1
- data/public/railwatch/assets/text-link-DHJ8BXx5.js +0 -1
- data/public/railwatch/assets/textarea-BeQtQyl5.js +0 -1
- data/public/railwatch/assets/timeline-CaKQVu48.js +0 -1
- data/public/railwatch/assets/transition-ksDpqhKJ.js +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2033d4d399f9d52afddba05178186c651c557d4a870decd78e0bf9cf90b6c9e7
|
|
4
|
+
data.tar.gz: 19cbbe8a3963391f28742b889fd5be1b68c006a59e2cefbbd0bcf2d33da1d3ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 43c847212862c33bf9bf9d6cb95354808ae3a033f79273351282c988a1334c83bb24f738789226f1feb9fc3798f60cba81bd460e2c783d8c1f8858ad1d4c1dc1
|
|
7
|
+
data.tar.gz: f73a3052b983d2493ca2a3e26a264110dc79ef37398badd3359fac7fe9f254f6eac3b6e3f34fc1583fb31434872f3e27faf9b31286cd7cb43544e5a3ba4514e3
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
filled in by the release commit, which is also the only commit that
|
|
7
7
|
touches lib/railwatch/version.rb and Gemfile.lock. See CONTRIBUTING.md. -->
|
|
8
8
|
|
|
9
|
+
## 0.7.0 (2026-09-23)
|
|
10
|
+
|
|
11
|
+
- The gem ships the dashboard's frontend source (`app/frontend`, without
|
|
12
|
+
tests) alongside its build, and `Railwatch.frontend_path` points at it.
|
|
13
|
+
Railwatch Cloud now builds its bundle from this source instead of
|
|
14
|
+
keeping its own copy, so the dashboard has one author. A host
|
|
15
|
+
application is unaffected: it still uses the prebuilt bundle and needs
|
|
16
|
+
no Node. The package grows by about 300 KB.
|
|
17
|
+
- The gem no longer carries the cloud's hosting pages and components
|
|
18
|
+
(marketing, sign-in, accounts, settings, usage, docs), which it never
|
|
19
|
+
rendered, or eleven components no page used. Three unused Radix
|
|
20
|
+
packages are removed from the dashboard build.
|
|
21
|
+
|
|
9
22
|
## 0.6.1 (2026-09-23)
|
|
10
23
|
|
|
11
24
|
- The docs describe embedded as the default install throughout: two
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type * as React from "react"
|
|
2
|
+
|
|
3
|
+
import { SidebarInset } from "@/components/ui/sidebar"
|
|
4
|
+
|
|
5
|
+
type AppContentProps = {
|
|
6
|
+
variant?: "header" | "sidebar"
|
|
7
|
+
} & React.ComponentProps<"main">
|
|
8
|
+
|
|
9
|
+
export function AppContent({
|
|
10
|
+
variant = "header",
|
|
11
|
+
children,
|
|
12
|
+
...props
|
|
13
|
+
}: AppContentProps) {
|
|
14
|
+
if (variant === "sidebar") {
|
|
15
|
+
return <SidebarInset {...props}>{children}</SidebarInset>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<main
|
|
20
|
+
className="mx-auto flex h-full w-full max-w-7xl flex-1 flex-col gap-4 rounded-xl"
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</main>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SVGAttributes } from "react"
|
|
2
|
+
|
|
3
|
+
// The Railwatch R with a gold track running into it. The R uses currentColor;
|
|
4
|
+
// the track is always gold.
|
|
5
|
+
export default function AppLogoIcon(props: SVGAttributes<SVGElement>) {
|
|
6
|
+
return (
|
|
7
|
+
<svg
|
|
8
|
+
viewBox="213 184 870 870"
|
|
9
|
+
fill="none"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
{...props}
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
d="M 236 324.989 L 236 404.978 496.750 405.239 L 757.500 405.500 765.665 408.577 C 777.060 412.870, 784.110 417.355, 792.381 425.574 C 833.878 466.807, 812.048 538.520, 752.263 557.363 C 737.593 561.987, 732.018 562.115, 560.250 561.798 C 471.562 561.634, 399 561.557, 399 561.626 C 399 561.695, 406.313 568.648, 415.250 577.077 C 436.108 596.747, 508.719 665.823, 525 681.483 C 612.468 765.614, 693.318 845.033, 770.500 922.639 L 840.500 993.023 951.250 993.011 C 1012.163 993.005, 1062 992.732, 1062 992.404 C 1062 992.076, 1056.942 986.113, 1050.761 979.154 C 1039.889 966.913, 1035.649 962.220, 1005.428 928.979 C 997.688 920.465, 984.624 906.075, 976.396 897 C 933.021 849.161, 888.142 799.872, 868.953 779 C 857.071 766.075, 841.562 749.200, 834.490 741.500 C 827.417 733.800, 814.456 719.721, 805.686 710.213 C 796.916 700.705, 789.994 692.673, 790.303 692.363 C 790.613 692.054, 795.578 690.983, 801.338 689.983 C 895.506 673.637, 967.601 596.363, 980.578 497.866 C 982.637 482.242, 982.086 446.289, 979.576 432.500 C 960.757 329.105, 884.022 255.740, 784.576 246.063 C 777.168 245.342, 687.144 245, 504.826 245 L 236 245 236 324.989"
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
/>
|
|
17
|
+
<path
|
|
18
|
+
d="M 243.550 507.838 C 244.072 508.299, 247.425 510.859, 251 513.526 C 294.327 545.849, 358.703 617.861, 503.521 796 C 560.192 865.711, 593.994 908.954, 627.414 954.500 L 642.090 974.500 689.045 975 C 714.871 975.275, 736 975.275, 735.999 975 C 735.994 973.773, 698.564 930.428, 663.901 891.507 C 571.946 788.257, 436.131 649.261, 367.500 588.162 C 325.285 550.581, 286.033 524.106, 252.457 510.567 C 243.188 506.829, 241.991 506.462, 243.550 507.838 M 236 520 C 236 521.800, 236.667 522, 242.655 522 C 249.247 522, 249.293 521.981, 247.500 520 C 246.164 518.524, 244.420 518, 240.845 518 C 236.667 518, 236 518.275, 236 520 M 236 532.500 L 236 537 249.067 537 L 262.134 537 258.446 532.500 L 254.759 528 245.380 528 L 236 528 236 532.500 M 236 553.500 L 236 562 258.500 562 C 270.875 562, 280.991 561.663, 280.981 561.250 C 280.970 560.837, 278.237 557.013, 274.908 552.750 L 268.854 545 252.427 545 L 236 545 236 553.500 M 235.909 585 C 235.859 589.950, 235.777 595.462, 235.727 597.250 L 235.636 600.500 273.840 600.762 L 312.044 601.024 302.772 588.569 L 293.500 576.114 264.750 576.057 L 236 576 235.909 585 M 235.570 627.477 C 235.212 629.389, 234.979 637.714, 235.053 645.977 L 235.188 661 295.571 661 L 355.955 661 342.326 642.500 L 328.698 624 282.460 624 L 236.223 624 235.570 627.477 M 236 717.750 L 236 741.500 324.591 741.326 C 373.315 741.230, 413.343 740.990, 413.541 740.792 C 413.739 740.594, 406.184 729.985, 396.752 717.216 L 379.603 694 307.802 694 L 236 694 236 717.750 M 236.235 813.250 L 236.500 842.500 362.358 842.754 C 472.189 842.975, 488.146 842.822, 487.658 841.552 C 487.351 840.751, 477.621 827.475, 466.036 812.048 L 444.973 784 340.471 784 L 235.970 784 236.235 813.250 M 235.683 898.750 C 234.872 900.147, 235.511 973.844, 236.341 974.675 C 237.491 975.825, 392.185 976.287, 495.665 975.450 L 581.829 974.753 578.959 970.126 C 575.681 964.845, 552.884 930.825, 539.500 911.243 L 530.500 898.075 383.309 898.038 C 302.354 898.017, 235.922 898.337, 235.683 898.750"
|
|
19
|
+
fill="#FFC22B"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import AppLogoIcon from "./app-logo-icon"
|
|
2
|
+
import AppWordmark from "./app-wordmark"
|
|
3
|
+
|
|
4
|
+
// The wordmark when there is room; the R tile once the sidebar collapses to icons.
|
|
5
|
+
export default function AppLogo() {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<div className="hidden aspect-square size-8 shrink-0 items-center justify-center rounded-md bg-[#0F1729] text-white group-data-[collapsible=icon]:flex">
|
|
9
|
+
<AppLogoIcon className="size-6" />
|
|
10
|
+
</div>
|
|
11
|
+
<AppWordmark className="h-4 w-auto group-data-[collapsible=icon]:hidden" />
|
|
12
|
+
</>
|
|
13
|
+
)
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
|
|
3
|
+
import { SidebarProvider } from "@/components/ui/sidebar"
|
|
4
|
+
|
|
5
|
+
interface AppShellProps {
|
|
6
|
+
children: React.ReactNode
|
|
7
|
+
variant?: "header" | "sidebar"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function AppShell({ children, variant = "header" }: AppShellProps) {
|
|
11
|
+
const [isOpen, setIsOpen] = useState(() =>
|
|
12
|
+
typeof window !== "undefined"
|
|
13
|
+
? localStorage.getItem("sidebar") !== "false"
|
|
14
|
+
: true,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const handleSidebarChange = (open: boolean) => {
|
|
18
|
+
setIsOpen(open)
|
|
19
|
+
|
|
20
|
+
if (typeof window !== "undefined") {
|
|
21
|
+
localStorage.setItem("sidebar", String(open))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (variant === "header") {
|
|
26
|
+
return <div className="flex min-h-screen w-full flex-col">{children}</div>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<SidebarProvider
|
|
31
|
+
defaultOpen={isOpen}
|
|
32
|
+
open={isOpen}
|
|
33
|
+
onOpenChange={handleSidebarChange}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</SidebarProvider>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { usePage } from "@inertiajs/react"
|
|
2
|
+
import { Search } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import { Breadcrumbs } from "@/components/breadcrumbs"
|
|
5
|
+
import { MobilePageSwitcher } from "@/components/railwatch/mobile-page-switcher"
|
|
6
|
+
import { Button } from "@/components/ui/button"
|
|
7
|
+
import { SidebarTrigger } from "@/components/ui/sidebar"
|
|
8
|
+
import type { BreadcrumbItem as BreadcrumbItemType, SharedProps } from "@/types"
|
|
9
|
+
|
|
10
|
+
export function AppSidebarHeader({
|
|
11
|
+
breadcrumbs = [],
|
|
12
|
+
onOpenCommandPalette,
|
|
13
|
+
}: {
|
|
14
|
+
breadcrumbs?: BreadcrumbItemType[]
|
|
15
|
+
onOpenCommandPalette?: () => void
|
|
16
|
+
}) {
|
|
17
|
+
const { environment } = usePage<SharedProps>().props
|
|
18
|
+
return (
|
|
19
|
+
<header className="bg-background/80 sticky top-0 z-20 flex h-12 shrink-0 items-center justify-between gap-2 border-b px-3 backdrop-blur md:h-11 md:border-0 md:bg-transparent md:px-6 md:pt-2 md:backdrop-blur-none">
|
|
20
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
21
|
+
<SidebarTrigger className="text-muted-foreground -ml-1" />
|
|
22
|
+
<div className="text-muted-foreground hidden min-w-0 text-xs md:block">
|
|
23
|
+
<Breadcrumbs breadcrumbs={breadcrumbs} />
|
|
24
|
+
</div>
|
|
25
|
+
{/* On phones the sidebar is a sheet, so the current page name (and a
|
|
26
|
+
quick way to jump between environment pages) lives up here. */}
|
|
27
|
+
<div className="min-w-0 md:hidden">
|
|
28
|
+
{environment ? (
|
|
29
|
+
<MobilePageSwitcher />
|
|
30
|
+
) : (
|
|
31
|
+
<span className="truncate text-sm font-medium">
|
|
32
|
+
{breadcrumbs[breadcrumbs.length - 1]?.title}
|
|
33
|
+
</span>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
{onOpenCommandPalette && (
|
|
38
|
+
<Button
|
|
39
|
+
type="button"
|
|
40
|
+
variant="outline"
|
|
41
|
+
size="sm"
|
|
42
|
+
className="text-muted-foreground h-8 gap-1.5"
|
|
43
|
+
onClick={onOpenCommandPalette}
|
|
44
|
+
>
|
|
45
|
+
<Search className="size-3.5" />
|
|
46
|
+
<span className="hidden sm:inline">Search</span>
|
|
47
|
+
<kbd className="bg-muted hidden rounded px-1 py-0.5 font-mono text-[10px] sm:inline">
|
|
48
|
+
⌘K
|
|
49
|
+
</kbd>
|
|
50
|
+
</Button>
|
|
51
|
+
)}
|
|
52
|
+
</header>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Link, usePage } from "@inertiajs/react"
|
|
2
|
+
import {
|
|
3
|
+
AlertOctagon,
|
|
4
|
+
BellRing,
|
|
5
|
+
BookOpen,
|
|
6
|
+
LayoutGrid,
|
|
7
|
+
Plug,
|
|
8
|
+
Users,
|
|
9
|
+
} from "lucide-react"
|
|
10
|
+
|
|
11
|
+
import { NavFooter } from "@/components/nav-footer"
|
|
12
|
+
import { NavMain } from "@/components/nav-main"
|
|
13
|
+
import { NavUser } from "@/components/nav-user"
|
|
14
|
+
import { EnvNav } from "@/components/railwatch/env-nav"
|
|
15
|
+
import { EnvSwitcher } from "@/components/railwatch/env-switcher"
|
|
16
|
+
import {
|
|
17
|
+
Sidebar,
|
|
18
|
+
SidebarContent,
|
|
19
|
+
SidebarFooter,
|
|
20
|
+
SidebarHeader,
|
|
21
|
+
SidebarMenu,
|
|
22
|
+
SidebarMenuButton,
|
|
23
|
+
SidebarMenuItem,
|
|
24
|
+
} from "@/components/ui/sidebar"
|
|
25
|
+
import {
|
|
26
|
+
alertsPath,
|
|
27
|
+
dashboardPath,
|
|
28
|
+
issuesPath,
|
|
29
|
+
settingsIntegrationsPath,
|
|
30
|
+
settingsMembersPath,
|
|
31
|
+
} from "@/routes"
|
|
32
|
+
import type { NavItem, SharedProps } from "@/types"
|
|
33
|
+
|
|
34
|
+
import AppLogo from "./app-logo"
|
|
35
|
+
|
|
36
|
+
// Integrations and Members are account features of the hosted platform;
|
|
37
|
+
// an embedded install has neither.
|
|
38
|
+
const mainNavItems = (embedded: boolean): NavItem[] => [
|
|
39
|
+
...(embedded
|
|
40
|
+
? []
|
|
41
|
+
: [{ title: "Dashboard", href: dashboardPath(), icon: LayoutGrid }]),
|
|
42
|
+
{ title: "Issues", href: issuesPath(), icon: AlertOctagon },
|
|
43
|
+
{ title: "Alerts", href: alertsPath(), icon: BellRing },
|
|
44
|
+
...(embedded
|
|
45
|
+
? []
|
|
46
|
+
: [
|
|
47
|
+
{ title: "Integrations", href: settingsIntegrationsPath(), icon: Plug },
|
|
48
|
+
{ title: "Members", href: settingsMembersPath(), icon: Users },
|
|
49
|
+
]),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
const footerNavItems = (embedded: boolean): NavItem[] => [
|
|
53
|
+
{
|
|
54
|
+
title: "Documentation",
|
|
55
|
+
href: embedded ? "https://railwatch.rebulk.com/docs" : "/docs",
|
|
56
|
+
icon: BookOpen,
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
export function AppSidebar() {
|
|
61
|
+
const { environment, applications, embedded } = usePage<SharedProps>().props
|
|
62
|
+
return (
|
|
63
|
+
<Sidebar collapsible="icon" variant="sidebar">
|
|
64
|
+
<SidebarHeader className="border-sidebar-border gap-0 border-b p-1.5">
|
|
65
|
+
{applications.length > 0 ? (
|
|
66
|
+
<EnvSwitcher />
|
|
67
|
+
) : (
|
|
68
|
+
<SidebarMenu>
|
|
69
|
+
<SidebarMenuItem>
|
|
70
|
+
<SidebarMenuButton size="lg" asChild>
|
|
71
|
+
<Link href={dashboardPath()} prefetch>
|
|
72
|
+
<AppLogo />
|
|
73
|
+
</Link>
|
|
74
|
+
</SidebarMenuButton>
|
|
75
|
+
</SidebarMenuItem>
|
|
76
|
+
</SidebarMenu>
|
|
77
|
+
)}
|
|
78
|
+
</SidebarHeader>
|
|
79
|
+
|
|
80
|
+
<SidebarContent className="gap-0 p-1.5">
|
|
81
|
+
{environment && <EnvNav />}
|
|
82
|
+
<NavMain
|
|
83
|
+
items={mainNavItems(!!embedded)}
|
|
84
|
+
label={environment ? "Account" : ""}
|
|
85
|
+
/>
|
|
86
|
+
</SidebarContent>
|
|
87
|
+
|
|
88
|
+
<SidebarFooter>
|
|
89
|
+
<NavFooter items={footerNavItems(!!embedded)} className="mt-auto" />
|
|
90
|
+
<NavUser />
|
|
91
|
+
</SidebarFooter>
|
|
92
|
+
</Sidebar>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SVGAttributes } from "react"
|
|
2
|
+
|
|
3
|
+
// The Railwatch wordmark: the R-with-track mark leading into "ail" in
|
|
4
|
+
// currentColor and "watch" in gold. Traced from the source artwork at 2x,
|
|
5
|
+
// so the viewBox is in that space. The paths need the evenodd rule to keep
|
|
6
|
+
// the counters in the a's open.
|
|
7
|
+
export default function AppWordmark(props: SVGAttributes<SVGElement>) {
|
|
8
|
+
return (
|
|
9
|
+
<svg
|
|
10
|
+
viewBox="736 448 2880 462"
|
|
11
|
+
fill="none"
|
|
12
|
+
role="img"
|
|
13
|
+
aria-label="Railwatch"
|
|
14
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M 1705.500 462.476 C 1679.632 468.154, 1662.773 487.210, 1661.280 512.458 C 1658.996 551.096, 1698.019 578.895, 1735.898 565.612 C 1760.384 557.027, 1775.688 532.957, 1772.167 508.569 C 1767.609 476.994, 1736.704 455.627, 1705.500 462.476 M 755 505 L 755 547 910.750 547.020 C 1008.152 547.032, 1069.122 547.411, 1073.500 548.031 C 1090.559 550.446, 1105.444 563.017, 1111.948 580.500 C 1115.051 588.843, 1115.127 606.469, 1112.101 616.072 C 1107.936 629.289, 1099.155 639.541, 1087 645.378 L 1080.500 648.500 986.833 649 C 935.316 649.275, 892.822 649.844, 892.401 650.265 C 891.981 650.686, 892.986 652.486, 894.636 654.265 C 903.408 663.727, 947.003 709.994, 950 713.023 C 951.925 714.969, 955.957 719.247, 958.960 722.530 C 967.637 732.017, 990.350 756.177, 1004.500 770.971 C 1011.650 778.447, 1027.400 795.119, 1039.500 808.021 C 1051.600 820.923, 1066.450 836.708, 1072.500 843.099 C 1113.697 886.618, 1120.661 893.869, 1122 894.638 C 1123.933 895.748, 1249 896.342, 1249 895.241 C 1249 894.303, 1212.449 854.365, 1176 815.478 C 1171.325 810.490, 1160.075 798.356, 1151 788.513 C 1141.925 778.671, 1124.600 760.080, 1112.500 747.201 C 1100.400 734.322, 1090.500 723.114, 1090.500 722.295 C 1090.500 721.107, 1092.523 720.710, 1100.500 720.333 C 1134.395 718.731, 1158.080 708.248, 1180.583 684.890 C 1197.777 667.042, 1209.845 643.641, 1214.564 619 C 1216.806 607.291, 1216.484 581.201, 1213.942 568.657 C 1203.036 514.829, 1164.112 476.027, 1109.947 464.989 C 1100.426 463.049, 1095.935 463, 927.593 463 L 755 463 755 505 M 1810.462 469.250 C 1810.201 469.938, 1810.103 563.425, 1810.244 677 L 1810.500 883.500 1860.250 883.759 L 1910 884.019 1910.061 875.259 C 1910.115 867.540, 1910.104 759.829, 1910.024 536.250 L 1910 468 1860.469 468 C 1821.764 468, 1810.833 468.273, 1810.462 469.250 M 1406.500 587.119 C 1386.693 588.773, 1375.094 590.376, 1355.500 594.169 C 1343.274 596.536, 1322.956 601.933, 1321.250 603.267 C 1320.291 604.017, 1320 612.608, 1320 640.122 C 1320 659.855, 1320.151 676, 1320.335 676 C 1320.519 676, 1323.332 675.159, 1326.585 674.130 C 1338.275 670.434, 1352.109 667.492, 1369 665.108 C 1387.180 662.542, 1402.440 661.667, 1430 661.607 C 1460.588 661.542, 1468.932 662.249, 1483.990 666.182 C 1504.644 671.577, 1521 687.839, 1521 702.978 C 1521 707.882, 1520.414 708.216, 1513.958 706.992 C 1491.021 702.642, 1408.872 700.655, 1384 703.848 C 1369.947 705.653, 1347.904 710.311, 1338.527 713.459 C 1292.218 729.005, 1269.982 767.734, 1279.656 816 C 1285.454 844.931, 1307.512 868.053, 1339.521 878.754 C 1347.519 881.428, 1350.554 882.273, 1360 884.454 C 1381.201 889.349, 1428.115 889.182, 1456 884.112 C 1476.908 880.311, 1500.740 870.482, 1517.319 858.821 C 1522.302 855.316, 1522.910 856.540, 1523.220 870.707 L 1523.500 883.500 1573.500 883.500 L 1623.500 883.500 1623.810 796.500 C 1624.174 694.503, 1623.863 689.383, 1615.998 667.831 C 1602.496 630.835, 1572.134 606.310, 1525.388 594.638 C 1509.615 590.700, 1505.054 589.984, 1476.830 587.017 C 1465.598 585.836, 1421.096 585.901, 1406.500 587.119 M 1667.462 598.250 C 1667.200 598.938, 1667.102 663.400, 1667.243 741.500 L 1667.500 883.500 1717.500 883.500 L 1767.500 883.500 1767.753 740.250 L 1768.007 597 1717.972 597 C 1678.865 597, 1667.833 597.273, 1667.462 598.250 M 1399.500 762.492 C 1380.658 766.022, 1372 774.922, 1372 790.761 C 1372 808.458, 1382.796 816.328, 1410.705 818.975 C 1453.844 823.065, 1491.426 814.703, 1508.908 797.124 C 1518.898 787.078, 1521.148 782.186, 1520.790 771.292 L 1520.500 762.500 1511.500 761.856 C 1493.821 760.591, 1407.017 761.084, 1399.500 762.492"
|
|
19
|
+
fill="currentColor"
|
|
20
|
+
fillRule="evenodd"
|
|
21
|
+
/>
|
|
22
|
+
<path
|
|
23
|
+
d="M 3277 681.471 L 3277 883.962 3279.250 884.508 C 3280.488 884.809, 3302.425 884.930, 3328 884.777 L 3374.500 884.500 3375 801 C 3375.561 707.275, 3374.748 716.403, 3383.496 705.665 C 3398.294 687.498, 3427.881 678.722, 3458.500 683.416 C 3481.414 686.928, 3493.243 697.343, 3500.156 720.088 C 3502.389 727.434, 3502.414 728.202, 3502.954 806 L 3503.500 884.500 3551.386 884.760 C 3587.861 884.958, 3599.621 884.729, 3600.738 883.802 C 3602.008 882.749, 3602.174 872.227, 3601.972 805.542 C 3601.746 730.884, 3601.066 705.568, 3598.922 692 C 3591.087 642.414, 3561.598 608.653, 3515.500 596.494 C 3512.200 595.624, 3504.100 594.261, 3497.500 593.465 C 3453.429 588.150, 3408.594 598.669, 3381.195 620.754 C 3378.828 622.662, 3376.578 623.911, 3376.195 623.529 C 3375.813 623.147, 3375.275 590.584, 3375 551.167 L 3374.500 479.500 3325.750 479.240 L 3277 478.981 3277 681.471 M 2783.667 520.667 C 2783.300 521.033, 2782.993 537.571, 2782.985 557.417 C 2782.976 577.263, 2782.624 594.043, 2782.203 594.706 C 2781.730 595.450, 2778.191 596.025, 2772.968 596.206 L 2764.500 596.500 2764.500 636.500 L 2764.500 676.500 2773.500 677.500 L 2782.500 678.500 2783.096 738.500 L 2783.692 798.500 2786.283 808.029 C 2791.367 826.728, 2795.423 835.943, 2803.236 846.542 C 2820.599 870.098, 2845.897 882.626, 2885.031 887.049 C 2896.314 888.324, 2951.623 887.765, 2960 886.292 L 2964.500 885.500 2964.500 846 L 2964.500 806.500 2937 805.958 C 2921.875 805.660, 2908.600 805.056, 2907.500 804.616 C 2896.677 800.280, 2889.616 793.637, 2885.804 784.202 C 2883.520 778.550, 2883.497 778.059, 2883.207 728.250 L 2882.913 678 2890.707 677.938 C 2894.993 677.904, 2913 677.781, 2930.723 677.665 C 2951.390 677.529, 2963.319 677.081, 2963.985 676.415 C 2964.677 675.723, 2964.936 662.218, 2964.762 635.938 L 2964.500 596.500 2924 596 L 2883.500 595.500 2883.237 559.087 C 2883.058 534.244, 2882.622 522.250, 2881.865 521.337 C 2880.967 520.255, 2871.570 520, 2832.544 520 C 2806.028 520, 2784.033 520.300, 2783.667 520.667 M 2552.634 587.091 C 2532.447 588.455, 2498.837 593.631, 2489 596.892 C 2485.941 597.906, 2481.069 599.349, 2474.653 601.140 C 2471.987 601.885, 2469.429 603.199, 2468.967 604.061 C 2468.506 604.923, 2468.212 621.349, 2468.314 640.564 C 2468.496 674.841, 2468.538 675.496, 2470.500 675.310 C 2471.600 675.206, 2477.675 673.712, 2484 671.990 C 2524.918 660.853, 2590.443 658.407, 2618.201 666.980 C 2635.175 672.223, 2648.165 686.509, 2649.728 701.654 L 2650.312 707.315 2645.406 706.623 C 2614.219 702.227, 2605.307 701.646, 2568.500 701.613 C 2528.271 701.576, 2520.140 702.366, 2496.919 708.571 C 2461.607 718.006, 2439.538 737.562, 2430.375 767.537 C 2426.496 780.227, 2426.196 807.961, 2429.802 820.500 C 2438.335 850.170, 2459.511 870.834, 2492.249 881.437 C 2508.248 886.619, 2522.958 888.422, 2549 888.392 C 2584.859 888.350, 2600.010 885.483, 2624 874.198 C 2629.879 871.432, 2647.278 860.213, 2647.833 858.831 C 2648.017 858.374, 2649.029 858, 2650.083 858 C 2651.873 858, 2652 858.854, 2652 870.893 C 2652 881.727, 2652.253 883.883, 2653.582 884.393 C 2655.648 885.186, 2741.352 885.186, 2743.418 884.393 C 2745.743 883.501, 2745.806 706.951, 2743.487 691.500 C 2734.995 634.926, 2698.185 600.772, 2634.081 589.988 C 2612.643 586.381, 2580.217 585.228, 2552.634 587.091 M 3109.500 591.528 C 3050.867 599.169, 3012.062 625.971, 2991.003 673.372 C 2987.539 681.169, 2984.395 691.815, 2981.514 705.500 C 2979.558 714.792, 2978.433 737.644, 2979.177 752.957 C 2982.872 828.974, 3024.942 875.495, 3100.500 887.116 C 3118.626 889.904, 3238.002 887.990, 3244.262 884.812 C 3245.905 883.977, 3246.006 881.319, 3245.762 845.209 L 3245.500 806.500 3183.500 805.964 C 3115.053 805.372, 3116.340 805.488, 3103.203 798.736 C 3079.639 786.626, 3069.485 756.900, 3076.649 721 C 3080.873 699.835, 3095.018 685.070, 3117.573 678.283 C 3122.970 676.659, 3128.861 676.498, 3183.500 676.472 C 3216.500 676.457, 3244.063 676.344, 3244.750 676.222 C 3245.725 676.049, 3246 667.242, 3246 636.137 L 3246 596.274 3238.750 595.175 C 3208.583 590.601, 3132.986 588.467, 3109.500 591.528 M 786.700 607.747 C 799.602 620.538, 811.920 633.724, 817.297 640.500 C 818.170 641.600, 821.751 646.100, 825.256 650.500 C 833.834 661.268, 873.458 714.122, 897.977 747.500 C 911.675 766.147, 917.863 774.803, 938.725 804.500 C 942.202 809.450, 948.749 818.617, 953.274 824.871 C 957.798 831.125, 963.490 839, 965.923 842.371 C 970.909 849.280, 974.415 854.082, 985.080 868.605 C 989.161 874.163, 995.200 882.600, 998.500 887.354 L 1004.500 895.998 1033.250 895.999 C 1050.407 896, 1062 895.623, 1062 895.066 C 1062 894.013, 1052.705 882.084, 1043.569 871.410 C 1035.523 862.010, 1027.543 852.531, 1012.917 835 C 1006.264 827.025, 999.847 819.375, 998.657 818 C 997.466 816.625, 988.182 805.825, 978.024 794 C 954.829 766.998, 957.339 769.897, 943.389 754 C 936.874 746.575, 930.362 739.150, 928.919 737.500 C 927.476 735.850, 920.717 728.223, 913.898 720.550 C 907.079 712.878, 897.922 702.528, 893.549 697.550 C 867.814 668.257, 840.996 640.571, 826.500 628.330 C 809.107 613.643, 785.722 598.317, 773.660 593.698 C 772.647 593.310, 778.515 599.632, 786.700 607.747 M 1933 596.589 C 1933 597.224, 1941.582 622.737, 1956.011 665 C 1960.987 679.575, 1967.721 699.375, 1970.976 709 C 1974.230 718.625, 1978.743 731.675, 1981.003 738 C 1983.264 744.325, 1986.868 754.675, 1989.012 761 C 1991.156 767.325, 1994.345 776.550, 1996.099 781.500 C 1997.853 786.450, 2001.880 797.925, 2005.048 807 C 2008.216 816.075, 2013.137 830.025, 2015.983 838 C 2018.829 845.975, 2021.992 854.975, 2023.011 858 C 2029.988 878.698, 2030.270 879.160, 2037.718 882.164 C 2043.327 884.426, 2044.399 884.496, 2073.500 884.498 C 2096.305 884.500, 2104.339 884.176, 2107 883.149 C 2121.304 877.628, 2121.835 876.967, 2129.987 854.500 C 2130.985 851.750, 2133.241 845.675, 2135 841 C 2136.759 836.325, 2139.054 830.138, 2140.099 827.250 C 2141.145 824.362, 2142.900 819.525, 2144 816.500 C 2145.100 813.475, 2146.857 808.638, 2147.903 805.750 C 2148.950 802.862, 2152.594 793.300, 2156 784.500 C 2159.406 775.700, 2163.012 766.250, 2164.012 763.500 C 2168.216 751.948, 2180.288 721.440, 2180.937 720.730 C 2182.009 719.556, 2184.572 725.539, 2190.045 742 C 2193.147 751.329, 2199.029 767.779, 2203.989 781 C 2205.743 785.675, 2207.546 790.625, 2207.995 792 C 2208.444 793.375, 2211.142 801.025, 2213.991 809 C 2216.840 816.975, 2222.678 833.850, 2226.966 846.500 C 2238.226 879.723, 2237.044 877.428, 2244.859 881.251 L 2251.500 884.500 2280.207 884.830 C 2310.645 885.180, 2315.755 884.696, 2324.521 880.632 C 2330.841 877.702, 2335.123 873.449, 2336.821 868.416 C 2339.121 861.600, 2343.766 849.181, 2352.498 826.500 C 2353.980 822.650, 2355.878 817.480, 2356.717 815.012 C 2357.555 812.544, 2359.537 807.695, 2361.120 804.237 C 2362.704 800.779, 2364 797.664, 2364 797.315 C 2364 796.563, 2372.662 773.280, 2377.697 760.500 C 2383.071 746.861, 2388.951 731.143, 2390.978 725 C 2391.977 721.975, 2393.792 717.025, 2395.012 714 C 2397.931 706.763, 2402.698 693.873, 2404.997 687 C 2406.009 683.975, 2408.714 676.550, 2411.008 670.500 C 2413.303 664.450, 2417.348 653.425, 2419.997 646 C 2424.731 632.733, 2430.370 617.144, 2435.303 603.681 C 2437.033 598.960, 2437.448 596.726, 2436.651 596.420 C 2436.018 596.178, 2414.125 596.096, 2388 596.240 L 2340.500 596.500 2334.387 615 C 2331.025 625.175, 2324.563 644.975, 2320.027 659 C 2315.490 673.025, 2309.172 692.375, 2305.986 702 C 2300.651 718.117, 2298.580 724.593, 2290.394 750.748 C 2288.802 755.834, 2286.987 759.997, 2286.360 759.998 C 2285.733 759.999, 2283.107 753.362, 2280.525 745.250 C 2277.942 737.138, 2274.271 726, 2272.367 720.500 C 2270.462 715, 2265.795 701.275, 2261.996 690 C 2258.196 678.725, 2252.336 661.625, 2248.973 652 C 2245.610 642.375, 2242.026 632.025, 2241.008 629 C 2235.846 613.659, 2232.744 606.338, 2230.724 604.727 C 2227.108 601.844, 2218.930 598.411, 2212.500 597.078 C 2203.416 595.195, 2160.419 596.098, 2152.667 598.335 C 2145.581 600.379, 2138.252 605.237, 2136.812 608.841 C 2136.229 610.304, 2135.389 612.400, 2134.947 613.500 C 2133.941 616, 2129.369 629.002, 2127.387 635 C 2126.569 637.475, 2125.514 640.400, 2125.043 641.500 C 2123.520 645.055, 2120.831 652.363, 2118.972 658 C 2117.974 661.025, 2115.737 667.325, 2114 672 C 2112.263 676.675, 2110.013 682.975, 2109 686 C 2107.987 689.025, 2105.746 695.325, 2104.022 700 C 2098.368 715.326, 2096.889 719.429, 2095.011 725 C 2093.992 728.025, 2091.813 734.100, 2090.170 738.500 C 2083.814 755.523, 2082 760.508, 2082 760.946 C 2082 764.084, 2078.346 754.155, 2075.028 742 C 2073.096 734.922, 2069.768 723.430, 2068.948 721 C 2068.484 719.625, 2067.148 715.125, 2065.979 711 C 2064.810 706.875, 2061.675 696.525, 2059.012 688 C 2056.349 679.475, 2052.735 667.775, 2050.980 662 C 2045.369 643.528, 2043.847 638.620, 2041.991 633 C 2040.992 629.975, 2039.188 624.125, 2037.983 620 C 2036.778 615.875, 2035.441 611.375, 2035.012 610 C 2034.583 608.625, 2033.677 605.475, 2032.998 603 C 2032.319 600.525, 2031.606 597.938, 2031.413 597.250 C 2031.049 595.950, 1933 595.291, 1933 596.589 M 751.380 603.452 C 750.295 606.281, 752.143 607, 760.500 607 C 769.264 607, 771.840 605.818, 768.462 603.348 C 765.814 601.412, 752.131 601.496, 751.380 603.452 M 751.667 612.667 C 750.752 613.581, 750.822 618.966, 751.750 619.145 C 755.748 619.916, 780 619.494, 780 618.654 C 780 618.080, 778.791 616.347, 777.313 614.805 C 774.684 612.060, 774.386 612, 763.480 612 C 757.349 612, 752.033 612.300, 751.667 612.667 M 750.321 630.606 C 749.982 631.490, 750.108 634.302, 750.602 636.856 L 751.500 641.500 774.250 641.769 C 786.763 641.917, 797 641.772, 797 641.447 C 797 640.238, 791.627 631.454, 790.150 630.250 C 787.598 628.168, 751.131 628.495, 750.321 630.606 M 750 665.861 L 750 676.721 755.250 677.352 C 762.948 678.277, 820.796 678.139, 821.379 677.195 C 821.828 676.470, 812.191 660.345, 809.040 656.549 C 807.934 655.216, 803.730 655, 778.878 655 L 750 655 750 665.861 M 750.444 697.285 C 750.168 698.004, 750.068 705.096, 750.221 713.046 L 750.500 727.500 803.250 727.759 C 862.431 728.049, 858.469 728.634, 852.750 720.448 C 850.962 717.890, 846.564 711.454, 842.975 706.148 L 836.450 696.500 793.698 696.239 C 759.243 696.029, 750.848 696.232, 750.444 697.285 M 760.500 754 C 752.556 754.361, 749.528 754.847, 749.600 755.750 C 749.655 756.438, 749.768 766.225, 749.850 777.500 L 750 798 826 798 C 873.668 798, 902 797.644, 902 797.044 C 902 795.717, 877.923 756.924, 875.284 754 C 875.036 753.725, 851.583 753.500, 823.167 753.500 C 794.750 753.500, 766.550 753.725, 760.500 754 M 2554 762.028 C 2539.188 763.176, 2531.544 765.819, 2525.351 771.932 C 2515.443 781.711, 2515.449 800.283, 2525.363 808.664 C 2534.138 816.083, 2543.018 817.974, 2569.142 817.988 C 2605.793 818.008, 2624.677 812.484, 2639.266 797.474 C 2647.120 789.393, 2650 782.751, 2650 772.717 C 2650 765.764, 2649.701 764.099, 2648.363 763.586 C 2646.597 762.908, 2584.680 760.959, 2571.500 761.165 C 2567.100 761.234, 2559.225 761.622, 2554 762.028 M 749.454 831.259 C 749.188 831.952, 749.090 846.689, 749.235 864.009 L 749.500 895.500 857.750 895.754 C 926.455 895.916, 966 895.658, 966 895.048 C 966 893.753, 961.842 886.805, 952.804 873 C 942.983 857.998, 929.818 837.362, 927.445 833.250 L 925.569 830 837.753 830 C 768.081 830, 749.837 830.260, 749.454 831.259"
|
|
24
|
+
fill="#FFC22B"
|
|
25
|
+
fillRule="evenodd"
|
|
26
|
+
/>
|
|
27
|
+
</svg>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Link } from "@inertiajs/react"
|
|
2
|
+
import { Fragment } from "react"
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Breadcrumb,
|
|
6
|
+
BreadcrumbItem,
|
|
7
|
+
BreadcrumbLink,
|
|
8
|
+
BreadcrumbList,
|
|
9
|
+
BreadcrumbPage,
|
|
10
|
+
BreadcrumbSeparator,
|
|
11
|
+
} from "@/components/ui/breadcrumb"
|
|
12
|
+
import type { BreadcrumbItem as BreadcrumbItemType } from "@/types"
|
|
13
|
+
|
|
14
|
+
export function Breadcrumbs({
|
|
15
|
+
breadcrumbs,
|
|
16
|
+
}: {
|
|
17
|
+
breadcrumbs: BreadcrumbItemType[]
|
|
18
|
+
}) {
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
{breadcrumbs.length > 0 && (
|
|
22
|
+
<Breadcrumb>
|
|
23
|
+
<BreadcrumbList>
|
|
24
|
+
{breadcrumbs.map((item, index) => {
|
|
25
|
+
const isLast = index === breadcrumbs.length - 1
|
|
26
|
+
return (
|
|
27
|
+
<Fragment key={index}>
|
|
28
|
+
<BreadcrumbItem>
|
|
29
|
+
{isLast ? (
|
|
30
|
+
<BreadcrumbPage>{item.title}</BreadcrumbPage>
|
|
31
|
+
) : (
|
|
32
|
+
<BreadcrumbLink asChild>
|
|
33
|
+
<Link href={item.href}>{item.title}</Link>
|
|
34
|
+
</BreadcrumbLink>
|
|
35
|
+
)}
|
|
36
|
+
</BreadcrumbItem>
|
|
37
|
+
{!isLast && <BreadcrumbSeparator />}
|
|
38
|
+
</Fragment>
|
|
39
|
+
)
|
|
40
|
+
})}
|
|
41
|
+
</BreadcrumbList>
|
|
42
|
+
</Breadcrumb>
|
|
43
|
+
)}
|
|
44
|
+
</>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LucideProps } from "lucide-react"
|
|
2
|
+
import type { ComponentType } from "react"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
type IconProps = {
|
|
7
|
+
iconNode: ComponentType<LucideProps>
|
|
8
|
+
} & Omit<LucideProps, "ref">
|
|
9
|
+
|
|
10
|
+
export function Icon({
|
|
11
|
+
iconNode: IconComponent,
|
|
12
|
+
className,
|
|
13
|
+
...props
|
|
14
|
+
}: IconProps) {
|
|
15
|
+
return <IconComponent className={cn("h-4 w-4", className)} {...props} />
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react"
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
export default function InputError({
|
|
6
|
+
messages,
|
|
7
|
+
className = "",
|
|
8
|
+
...props
|
|
9
|
+
}: HTMLAttributes<HTMLParagraphElement> & { messages?: string[] }) {
|
|
10
|
+
return messages ? (
|
|
11
|
+
<p
|
|
12
|
+
{...props}
|
|
13
|
+
className={cn("text-sm text-red-600 dark:text-red-400", className)}
|
|
14
|
+
>
|
|
15
|
+
{messages.join(", ")}
|
|
16
|
+
</p>
|
|
17
|
+
) : null
|
|
18
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef } from "react"
|
|
2
|
+
|
|
3
|
+
import { Icon } from "@/components/icon"
|
|
4
|
+
import {
|
|
5
|
+
SidebarGroup,
|
|
6
|
+
SidebarGroupContent,
|
|
7
|
+
SidebarMenu,
|
|
8
|
+
SidebarMenuButton,
|
|
9
|
+
SidebarMenuItem,
|
|
10
|
+
} from "@/components/ui/sidebar"
|
|
11
|
+
import type { NavItem } from "@/types"
|
|
12
|
+
|
|
13
|
+
export function NavFooter({
|
|
14
|
+
items,
|
|
15
|
+
className,
|
|
16
|
+
...props
|
|
17
|
+
}: ComponentPropsWithoutRef<typeof SidebarGroup> & {
|
|
18
|
+
items: NavItem[]
|
|
19
|
+
}) {
|
|
20
|
+
return (
|
|
21
|
+
<SidebarGroup
|
|
22
|
+
{...props}
|
|
23
|
+
className={`group-data-[collapsible=icon]:p-0 ${className ?? ""}`}
|
|
24
|
+
>
|
|
25
|
+
<SidebarGroupContent>
|
|
26
|
+
<SidebarMenu>
|
|
27
|
+
{items.map((item) => (
|
|
28
|
+
<SidebarMenuItem key={item.title}>
|
|
29
|
+
<SidebarMenuButton
|
|
30
|
+
asChild
|
|
31
|
+
className="text-neutral-600 hover:text-neutral-800 dark:text-neutral-300 dark:hover:text-neutral-100"
|
|
32
|
+
>
|
|
33
|
+
<a href={item.href} target="_blank" rel="noopener noreferrer">
|
|
34
|
+
{item.icon && (
|
|
35
|
+
<Icon iconNode={item.icon} className="h-5 w-5" />
|
|
36
|
+
)}
|
|
37
|
+
<span>{item.title}</span>
|
|
38
|
+
</a>
|
|
39
|
+
</SidebarMenuButton>
|
|
40
|
+
</SidebarMenuItem>
|
|
41
|
+
))}
|
|
42
|
+
</SidebarMenu>
|
|
43
|
+
</SidebarGroupContent>
|
|
44
|
+
</SidebarGroup>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Link, usePage } from "@inertiajs/react"
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
SidebarGroup,
|
|
5
|
+
SidebarGroupLabel,
|
|
6
|
+
SidebarMenu,
|
|
7
|
+
SidebarMenuButton,
|
|
8
|
+
SidebarMenuItem,
|
|
9
|
+
} from "@/components/ui/sidebar"
|
|
10
|
+
import type { NavItem } from "@/types"
|
|
11
|
+
|
|
12
|
+
export function NavMain({
|
|
13
|
+
items = [],
|
|
14
|
+
label = "Platform",
|
|
15
|
+
}: {
|
|
16
|
+
items: NavItem[]
|
|
17
|
+
label?: string
|
|
18
|
+
}) {
|
|
19
|
+
const page = usePage()
|
|
20
|
+
return (
|
|
21
|
+
<SidebarGroup className="p-0">
|
|
22
|
+
{label && <SidebarGroupLabel>{label}</SidebarGroupLabel>}
|
|
23
|
+
<SidebarMenu>
|
|
24
|
+
{items.map((item) => (
|
|
25
|
+
<SidebarMenuItem key={item.title}>
|
|
26
|
+
<SidebarMenuButton
|
|
27
|
+
asChild
|
|
28
|
+
isActive={page.url.startsWith(item.href)}
|
|
29
|
+
tooltip={{ children: item.title }}
|
|
30
|
+
>
|
|
31
|
+
<Link href={item.href} prefetch>
|
|
32
|
+
{item.icon && <item.icon />}
|
|
33
|
+
<span>{item.title}</span>
|
|
34
|
+
</Link>
|
|
35
|
+
</SidebarMenuButton>
|
|
36
|
+
</SidebarMenuItem>
|
|
37
|
+
))}
|
|
38
|
+
</SidebarMenu>
|
|
39
|
+
</SidebarGroup>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { usePage } from "@inertiajs/react"
|
|
2
|
+
import { ChevronsUpDown } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuTrigger,
|
|
8
|
+
} from "@/components/ui/dropdown-menu"
|
|
9
|
+
import {
|
|
10
|
+
SidebarMenu,
|
|
11
|
+
SidebarMenuButton,
|
|
12
|
+
SidebarMenuItem,
|
|
13
|
+
useSidebar,
|
|
14
|
+
} from "@/components/ui/sidebar"
|
|
15
|
+
import { UserInfo } from "@/components/user-info"
|
|
16
|
+
import { UserMenuContent } from "@/components/user-menu-content"
|
|
17
|
+
import { useIsMobile } from "@/hooks/use-mobile"
|
|
18
|
+
|
|
19
|
+
export function NavUser() {
|
|
20
|
+
const { auth } = usePage().props
|
|
21
|
+
const { state } = useSidebar()
|
|
22
|
+
const isMobile = useIsMobile()
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<SidebarMenu>
|
|
26
|
+
<SidebarMenuItem>
|
|
27
|
+
<DropdownMenu>
|
|
28
|
+
<DropdownMenuTrigger asChild>
|
|
29
|
+
<SidebarMenuButton
|
|
30
|
+
size="default"
|
|
31
|
+
className="data-[state=open]:bg-sidebar-accent group gap-2"
|
|
32
|
+
>
|
|
33
|
+
<UserInfo user={auth.user} />
|
|
34
|
+
<ChevronsUpDown className="ml-auto size-4" />
|
|
35
|
+
</SidebarMenuButton>
|
|
36
|
+
</DropdownMenuTrigger>
|
|
37
|
+
<DropdownMenuContent
|
|
38
|
+
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
|
|
39
|
+
align="end"
|
|
40
|
+
side={
|
|
41
|
+
isMobile ? "bottom" : state === "collapsed" ? "left" : "bottom"
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
<UserMenuContent auth={auth} />
|
|
45
|
+
</DropdownMenuContent>
|
|
46
|
+
</DropdownMenu>
|
|
47
|
+
</SidebarMenuItem>
|
|
48
|
+
</SidebarMenu>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, useState } from "react"
|
|
2
|
+
import type { ReactNode } from "react"
|
|
3
|
+
|
|
4
|
+
interface ChartHoverContextValue {
|
|
5
|
+
hoveredKey: string | null
|
|
6
|
+
setHoveredKey: (key: string | null) => void
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const noop = () => undefined
|
|
10
|
+
const fallback: ChartHoverContextValue = {
|
|
11
|
+
hoveredKey: null,
|
|
12
|
+
setHoveredKey: noop,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const ChartHoverContext = createContext<ChartHoverContextValue>(fallback)
|
|
16
|
+
|
|
17
|
+
// Links a chart to the table below it: hovering a chart point (bucket time)
|
|
18
|
+
// or a table row (its group_hash) sets one shared `hoveredKey`, so
|
|
19
|
+
// `SeriesChart`/`Sparkline` can highlight the matching point and `DataTable`
|
|
20
|
+
// can style the matching row. Using the context outside a provider is safe —
|
|
21
|
+
// it falls back to a no-op so call sites don't need to check.
|
|
22
|
+
export function ChartHoverProvider({ children }: { children: ReactNode }) {
|
|
23
|
+
const [hoveredKey, setHoveredKey] = useState<string | null>(null)
|
|
24
|
+
const value = useMemo(() => ({ hoveredKey, setHoveredKey }), [hoveredKey])
|
|
25
|
+
return (
|
|
26
|
+
<ChartHoverContext.Provider value={value}>
|
|
27
|
+
{children}
|
|
28
|
+
</ChartHoverContext.Provider>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function useChartHover() {
|
|
33
|
+
return useContext(ChartHoverContext)
|
|
34
|
+
}
|