PortLayout.razor 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 overflow-visible">
  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="truncate">
  38. <span class="text-zinc-500">
  39. @(index + 1)
  40. </span>
  41. <span> - </span>
  42. <span>@other!.Resource</span>
  43. </div>
  44. @if (otherGroup != null)
  45. {
  46. <div class="text-[9px] text-zinc-400 leading-tight">
  47. @otherGroup.Type — @otherGroup.Speed Gbps
  48. (port @(other.PortIndex + 1) / @otherGroup.Count)
  49. </div>
  50. }
  51. </div>
  52. </NavLink>
  53. }
  54. else
  55. {
  56. <button class="block text-left"
  57. @onclick="() => HandlePortClick(port)">
  58. <div class="@PortClass(false)">
  59. <div>
  60. <span class="text-zinc-500">
  61. @(index + 1)
  62. </span>
  63. <span> - </span>
  64. <span class="text-zinc-700 italic">free</span>
  65. </div>
  66. <div class="text-[9px] leading-tight invisible">
  67. placeholder
  68. </div>
  69. </div>
  70. </button>
  71. }
  72. }
  73. </div>
  74. }
  75. @code {
  76. [Parameter] public string ResourceName { get; set; } = "";
  77. [Parameter] public int PortGroupIndex { get; set; }
  78. [Parameter] public Port? PortGroup { get; set; }
  79. [Parameter] public EventCallback<PortReference> OnPortClicked { get; set; }
  80. private List<Connection> _connections = new();
  81. private readonly Dictionary<string, IPortResource?> _portResources = new();
  82. protected override async Task OnParametersSetAsync()
  83. {
  84. _connections = (await Repository.GetConnectionsAsync()).ToList();
  85. }
  86. async Task HandlePortClick(PortReference port)
  87. {
  88. if (OnPortClicked.HasDelegate)
  89. await OnPortClicked.InvokeAsync(port);
  90. }
  91. string PortClass(bool connected)
  92. {
  93. return $@"
  94. w-28
  95. min-h-12
  96. py-1
  97. border-r
  98. border-b
  99. border-zinc-800
  100. text-[10px]
  101. leading-snug
  102. flex
  103. flex-col
  104. justify-start
  105. px-1
  106. transition
  107. hover:bg-zinc-800
  108. {(connected ? "bg-blue-950/40 text-blue-200" : "text-zinc-500")}
  109. ";
  110. }
  111. Connection? GetConnection(PortReference port)
  112. {
  113. return _connections.FirstOrDefault(c =>
  114. (c.A.Resource == port.Resource &&
  115. c.A.PortGroup == port.PortGroup &&
  116. c.A.PortIndex == port.PortIndex)
  117. ||
  118. (c.B.Resource == port.Resource &&
  119. c.B.PortGroup == port.PortGroup &&
  120. c.B.PortIndex == port.PortIndex));
  121. }
  122. PortReference? GetOther(Connection? conn, PortReference port)
  123. {
  124. if (conn == null)
  125. return null;
  126. if (conn.A.Resource == port.Resource &&
  127. conn.A.PortGroup == port.PortGroup &&
  128. conn.A.PortIndex == port.PortIndex)
  129. return conn.B;
  130. return conn.A;
  131. }
  132. Port? GetDestinationPortGroup(PortReference other)
  133. {
  134. if (!_portResources.ContainsKey(other.Resource))
  135. {
  136. var res = Repository.GetByNameAsync(other.Resource).Result;
  137. if (res is IPortResource pr)
  138. _portResources[other.Resource] = pr;
  139. else
  140. _portResources[other.Resource] = null;
  141. }
  142. var portResource = _portResources[other.Resource];
  143. if (portResource?.Ports == null)
  144. return null;
  145. if (other.PortGroup < 0 || other.PortGroup >= portResource.Ports.Count)
  146. return null;
  147. return portResource.Ports[other.PortGroup];
  148. }
  149. }