HardwareTreePage.razor 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. .OrderBy(h => h.Kind)
  35. .ThenBy(h => h.HardwareName)
  36. .GroupBy(h => h.Kind))
  37. {
  38. <!-- Hardware Kind Header -->
  39. <div class="mb-6">
  40. <div class="text-xs text-zinc-500 uppercase tracking-wider mb-3">
  41. @group.Key
  42. </div>
  43. <ul class="space-y-4">
  44. @foreach (var hardware in group)
  45. {
  46. <li>
  47. <!-- Hardware -->
  48. <NavLink href="@($"/resources/hardware/{hardware.HardwareName}")" class="block">
  49. @if (hardware.Systems.Any())
  50. {
  51. <div class="text-zinc-100">
  52. @hardware.HardwareName (@hardware.Systems.Count / @hardware.Systems.Sum(s => s.Services.Count))
  53. </div>
  54. }
  55. else
  56. {
  57. <div class="text-zinc-100">
  58. @hardware.HardwareName
  59. </div>
  60. }
  61. </NavLink>
  62. @if (hardware.Systems.Any())
  63. {
  64. <ul class="ml-4 mt-2 border-l border-zinc-800 pl-4 space-y-2">
  65. @foreach (var system in hardware.Systems.OrderBy(s => s.SystemName))
  66. {
  67. <li>
  68. <!-- System -->
  69. <NavLink href="@($"/resources/systems/{system.SystemName}")" class="block">
  70. @if (system.Services.Any())
  71. {
  72. <div class="text-zinc-300">
  73. └─ @system.SystemName (@system.Services.Count)
  74. </div>
  75. }
  76. else
  77. {
  78. <div class="text-zinc-300">
  79. └─ @system.SystemName
  80. </div>
  81. }
  82. </NavLink>
  83. @if (system.Services.Any())
  84. {
  85. <ul class="ml-4 mt-1 space-y-1">
  86. @foreach (var service in system.Services.OrderBy(s => s))
  87. {
  88. <NavLink href="@($"/resources/services/{service}")"
  89. class="block">
  90. <li class="text-zinc-500">
  91. > @service
  92. </li>
  93. </NavLink>
  94. }
  95. </ul>
  96. }
  97. </li>
  98. }
  99. </ul>
  100. }
  101. </li>
  102. }
  103. </ul>
  104. </div>
  105. }
  106. }
  107. </div>
  108. @code {
  109. private List<HardwareTree>? _tree;
  110. protected override async Task OnInitializedAsync()
  111. {
  112. _tree = await HardwareRepository.GetTreeAsync();
  113. }
  114. }