PortLayout.razor 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. @using RackPeek.Domain.Persistence
  2. @using RackPeek.Domain.Resources.Connections
  3. @using RackPeek.Domain.Resources.Servers
  4. @using RackPeek.Domain.Resources.SubResources
  5. @inject IResourceCollection Repository
  6. @if (PortGroup is null || string.IsNullOrWhiteSpace(ResourceName))
  7. {
  8. <div class="text-zinc-500 text-xs">
  9. No ports available.
  10. </div>
  11. }
  12. else
  13. {
  14. <div class="flex flex-wrap border border-zinc-800 w-fit">
  15. @for (var i = 0; i < PortGroup.Count; i++)
  16. {
  17. var index = i;
  18. var port = new PortReference
  19. {
  20. Resource = ResourceName,
  21. PortGroup = PortGroupIndex,
  22. PortIndex = index
  23. };
  24. var conn = GetConnection(port);
  25. var other = GetOther(conn, port);
  26. var isConnected = other != null;
  27. Port? otherGroup = null;
  28. if (isConnected)
  29. {
  30. otherGroup = GetDestinationPortGroup(other!);
  31. }
  32. if (isConnected)
  33. {
  34. <NavLink href="@($"resources/hardware/{Uri.EscapeDataString(other!.Resource)}")"
  35. class="block">
  36. <div class="@PortClass(true)">
  37. <div class="text-zinc-500">
  38. @(index + 1)
  39. </div>
  40. <div class="truncate">
  41. @other!.Resource
  42. </div>
  43. @if (otherGroup != null)
  44. {
  45. <div class="text-[9px] text-zinc-400 leading-tight">
  46. @otherGroup.Type — @otherGroup.Speed Gbps
  47. (port @(other.PortIndex + 1) / @otherGroup.Count)
  48. </div>
  49. }
  50. </div>
  51. </NavLink>
  52. }
  53. else
  54. {
  55. <button class="block text-left"
  56. @onclick="() => HandlePortClick(port)">
  57. <div class="@PortClass(false)">
  58. <div class="text-zinc-500">
  59. @(index + 1)
  60. </div>
  61. <div class="text-zinc-700 italic">
  62. free
  63. </div>
  64. </div>
  65. </button>
  66. }
  67. }
  68. </div>
  69. }
  70. @code {
  71. [Parameter] public string ResourceName { get; set; } = "";
  72. [Parameter] public int PortGroupIndex { get; set; }
  73. [Parameter] public Port? PortGroup { get; set; }
  74. [Parameter] public EventCallback<PortReference> OnPortClicked { get; set; }
  75. private List<Connection> _connections = new();
  76. private readonly Dictionary<string, IPortResource?> _portResources = new();
  77. protected override async Task OnParametersSetAsync()
  78. {
  79. _connections = (await Repository.GetConnectionsAsync()).ToList();
  80. }
  81. async Task HandlePortClick(PortReference port)
  82. {
  83. if (OnPortClicked.HasDelegate)
  84. await OnPortClicked.InvokeAsync(port);
  85. }
  86. string PortClass(bool connected)
  87. {
  88. return $@"
  89. w-28
  90. h-12
  91. border-r
  92. border-b
  93. border-zinc-800
  94. text-[10px]
  95. leading-tight
  96. flex
  97. flex-col
  98. justify-center
  99. px-1
  100. transition
  101. hover:bg-zinc-800
  102. {(connected ? "bg-blue-950/40 text-blue-200" : "text-zinc-500")}
  103. ";
  104. }
  105. Connection? GetConnection(PortReference port)
  106. {
  107. return _connections.FirstOrDefault(c =>
  108. (c.A.Resource == port.Resource &&
  109. c.A.PortGroup == port.PortGroup &&
  110. c.A.PortIndex == port.PortIndex)
  111. ||
  112. (c.B.Resource == port.Resource &&
  113. c.B.PortGroup == port.PortGroup &&
  114. c.B.PortIndex == port.PortIndex));
  115. }
  116. PortReference? GetOther(Connection? conn, PortReference port)
  117. {
  118. if (conn == null)
  119. return null;
  120. if (conn.A.Resource == port.Resource &&
  121. conn.A.PortGroup == port.PortGroup &&
  122. conn.A.PortIndex == port.PortIndex)
  123. return conn.B;
  124. return conn.A;
  125. }
  126. Port? GetDestinationPortGroup(PortReference other)
  127. {
  128. if (!_portResources.ContainsKey(other.Resource))
  129. {
  130. var res = Repository.GetByNameAsync(other.Resource).Result;
  131. if (res is IPortResource pr)
  132. _portResources[other.Resource] = pr;
  133. else
  134. _portResources[other.Resource] = null;
  135. }
  136. var portResource = _portResources[other.Resource];
  137. if (portResource?.Ports == null)
  138. return null;
  139. if (other.PortGroup < 0 || other.PortGroup >= portResource.Ports.Count)
  140. return null;
  141. return portResource.Ports[other.PortGroup];
  142. }
  143. }