HardwareTreePage.razor 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. @page "/hardware/tree"
  2. @using RackPeek.Domain.Resources.Hardware
  3. @inject IHardwareRepository HardwareRepository
  4. <PageTitle>Hardware</PageTitle>
  5. <h1 class="text-lg text-zinc-100">
  6. Hardware
  7. </h1>
  8. <div class="min-h-screen bg-zinc-950 text-zinc-200 font-mono p-6">
  9. <nav class="space-x-6 text-sm mb-4">
  10. <NavLink href="/servers/list" class="hover:text-emerald-400" activeClass="text-emerald-400 font-semibold">
  11. Servers
  12. </NavLink>
  13. <NavLink href="/switches/list" class="hover:text-emerald-400" activeClass="text-emerald-400 font-semibold">
  14. Switches
  15. </NavLink>
  16. <NavLink href="/desktops/list" class="hover:text-emerald-400" activeClass="text-emerald-400 font-semibold">
  17. Desktops
  18. </NavLink>
  19. <NavLink href="/accesspoints/list" class="hover:text-emerald-400" activeClass="text-emerald-400 font-semibold">
  20. AccessPoints
  21. </NavLink>
  22. </nav>
  23. @if (_tree is null)
  24. {
  25. <div class="text-zinc-500">loading tree…</div>
  26. }
  27. else if (_tree.Count == 0)
  28. {
  29. <div class="text-zinc-500">no resources found</div>
  30. }
  31. else
  32. {
  33. @foreach (var group in _tree
  34. .OrderByDescending(h => h.Systems.Count)
  35. .ThenBy(h => h.Kind)
  36. .ThenBy(h => h.HardwareName)
  37. .GroupBy(h => h.Kind))
  38. {
  39. <!-- Hardware Kind Header -->
  40. <div class="mb-6">
  41. <div class="text-xs text-zinc-500 uppercase tracking-wider mb-3">
  42. @group.Key
  43. </div>
  44. <ul class="space-y-4">
  45. @foreach (var hardware in group)
  46. {
  47. <li>
  48. <!-- Hardware -->
  49. <NavLink href="@($"/resources/hardware/{hardware.HardwareName}")" class="block">
  50. @if (hardware.Systems.Any())
  51. {
  52. <div class="text-zinc-100">
  53. @hardware.HardwareName (@hardware.Systems.Count / @hardware.Systems.Sum(s => s.Services.Count))
  54. </div>
  55. }
  56. else
  57. {
  58. <div class="text-zinc-100">
  59. @hardware.HardwareName
  60. </div>
  61. }
  62. </NavLink>
  63. @if (hardware.Systems.Any())
  64. {
  65. <ul class="ml-4 mt-2 border-l border-zinc-800 pl-4 space-y-2">
  66. @foreach (var system in hardware.Systems.OrderByDescending(s => s.Services.Count).ThenBy(s => s.SystemName))
  67. {
  68. <li>
  69. <!-- System -->
  70. <NavLink href="@($"/resources/systems/{system.SystemName}")" class="block">
  71. @if (system.Services.Any())
  72. {
  73. <div class="text-zinc-300">
  74. └─ @system.SystemName (@system.Services.Count)
  75. </div>
  76. }
  77. else
  78. {
  79. <div class="text-zinc-300">
  80. └─ @system.SystemName
  81. </div>
  82. }
  83. </NavLink>
  84. @if (system.Services.Any())
  85. {
  86. <ul class="ml-4 mt-1 space-y-1">
  87. @foreach (var service in system.Services.OrderBy(s => s))
  88. {
  89. <NavLink href="@($"/resources/services/{service}")"
  90. class="block">
  91. <li class="text-zinc-500">
  92. > @service
  93. </li>
  94. </NavLink>
  95. }
  96. </ul>
  97. }
  98. </li>
  99. }
  100. </ul>
  101. }
  102. </li>
  103. }
  104. </ul>
  105. </div>
  106. }
  107. }
  108. </div>
  109. @code {
  110. private List<HardwareTree>? _tree;
  111. protected override async Task OnInitializedAsync()
  112. {
  113. _tree = await HardwareRepository.GetTreeAsync();
  114. }
  115. }