ServerCardComponent.razor 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. @using RackPeek.Domain.Resources.Hardware.Models
  2. @using RackPeek.Domain.Resources.Hardware.Servers
  3. @using RackPeek.Domain.Resources.Hardware.Servers.Cpus
  4. @using RackPeek.Domain.Resources.Hardware.Servers.Drives
  5. @using RackPeek.Web.Components.Modals
  6. @inject AddCpuUseCase AddCpuUseCase
  7. @inject RemoveCpuUseCase RemoveCpuUseCase
  8. @inject UpdateCpuUseCase UpdateCpuUseCase
  9. @inject AddDrivesUseCase AddDriveUseCase
  10. @inject RemoveDriveUseCase RemoveDriveUseCase
  11. @inject UpdateDriveUseCase UpdateDriveUseCase
  12. @inject GetServerUseCase GetServerUseCase
  13. @inject UpdateServerUseCase UpdateServerUseCase
  14. <div class="border border-zinc-800 rounded p-4 bg-zinc-900">
  15. <div class="flex justify-between items-center mb-3">
  16. <div class="text-zinc-100">
  17. @Server.Name
  18. </div>
  19. @if (Server.Ipmi == true)
  20. {
  21. <span class="text-xs text-emerald-400">IPMI</span>
  22. }
  23. </div>
  24. <div class="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
  25. <div>
  26. <div class="flex items-center justify-between mb-1 group">
  27. <div class="text-zinc-400">CPU
  28. <button
  29. class="hover:text-emerald-400 group-hover:opacity-100 transition"
  30. title="Add CPU"
  31. @onclick="OpenAddCpu">
  32. +
  33. </button>
  34. </div>
  35. </div>
  36. @if (Server.Cpus?.Any() == true)
  37. {
  38. <!-- CPU rows -->
  39. @foreach (var cpu in Server.Cpus)
  40. {
  41. <div
  42. class="flex items-center justify-between text-zinc-300 group hover:bg-zinc-800/40 rounded px-1 py-0.5">
  43. <div class="flex gap-2 group-hover:opacity-100 transition">
  44. <button
  45. class="hover:text-emerald-400"
  46. title="Edit CPU"
  47. @onclick="() => OpenEditCpu(cpu)">
  48. @cpu.Model — @cpu.Cores cores / @cpu.Threads threads
  49. </button>
  50. </div>
  51. </div>
  52. }
  53. }
  54. </div>
  55. <div>
  56. <div class="text-zinc-400 mb-1">RAM
  57. @if (Server.Ram is null)
  58. {
  59. <button
  60. class="hover:text-emerald-400 group-hover:opacity-100 transition"
  61. title="Add RAM"
  62. @onclick="EditRam">
  63. +
  64. </button>
  65. }
  66. </div>
  67. @if (Server.Ram is not null)
  68. {
  69. <div
  70. class="flex items-center justify-between text-zinc-300 group hover:bg-zinc-800/40 rounded px-1 py-0.5">
  71. <div class="flex gap-2 group-hover:opacity-100 transition">
  72. <button
  73. class="hover:text-emerald-400"
  74. title="Edit RAM"
  75. @onclick="EditRam">
  76. @($"{Server.Ram.Size} GB {@Server.Ram.Mts} MT/s")
  77. </button>
  78. </div>
  79. </div>
  80. }
  81. </div>
  82. <div>
  83. <div class="flex items-center justify-between mb-1 group">
  84. <div class="text-zinc-400">Drives
  85. <button
  86. class="hover:text-emerald-400 group-hover:opacity-100 transition"
  87. title="Add Drive"
  88. @onclick="OpenAddDrive">
  89. +
  90. </button>
  91. </div>
  92. </div>
  93. @if (Server.Drives?.Any() == true)
  94. {
  95. @foreach (var drive in Server.Drives)
  96. {
  97. <div
  98. class="flex items-center justify-between text-zinc-300 group hover:bg-zinc-800/40 rounded px-1 py-0.5">
  99. <div class="flex gap-2 group-hover:opacity-100 transition">
  100. <button
  101. class="hover:text-emerald-400"
  102. title="Edit Drive"
  103. @onclick="() => OpenEditDrives(drive)">
  104. @drive.Type — @drive.Size GB
  105. </button>
  106. </div>
  107. </div>
  108. }
  109. }
  110. </div>
  111. @if (Server.Nics?.Any() == true)
  112. {
  113. <div>
  114. <div class="text-zinc-400 mb-1">NICs</div>
  115. @foreach (var nic in Server.Nics)
  116. {
  117. <div class="text-zinc-300">
  118. @nic.Type — @nic.Speed Gbps (@nic.Ports ports)
  119. </div>
  120. }
  121. </div>
  122. }
  123. @if (Server.Gpus?.Any() == true)
  124. {
  125. <div>
  126. <div class="text-zinc-400 mb-1">GPU</div>
  127. @foreach (var gpu in Server.Gpus)
  128. {
  129. <div class="text-zinc-300">
  130. @gpu.Model — @gpu.Vram GB VRAM
  131. </div>
  132. }
  133. </div>
  134. }
  135. </div>
  136. </div>
  137. <CpuModal
  138. IsOpen="@_cpuModalOpen"
  139. IsOpenChanged="v => _cpuModalOpen = v"
  140. Value="@_editingCpu"
  141. OnSubmit="HandleCpuSubmit"
  142. OnDelete="HandleCpuDelete"/>
  143. <RamModal
  144. IsOpen="@_isRamModalOpen"
  145. IsOpenChanged="v => _isRamModalOpen = v"
  146. Value="@Server.Ram"
  147. OnSubmit="HandleRamSubmit"/>
  148. <DriveModal
  149. IsOpen="@_driveModalOpen"
  150. IsOpenChanged="v => _driveModalOpen = v"
  151. Value="@_editingDrive"
  152. OnSubmit="HandleDriveSubmit"
  153. OnDelete="HandleDriveDelete"/>
  154. @code {
  155. [Parameter] [EditorRequired]
  156. public Server Server { get; set; } = default!;
  157. #region RAM
  158. private bool _isRamModalOpen;
  159. private void EditRam()
  160. {
  161. _isRamModalOpen = true;
  162. }
  163. private async Task HandleRamSubmit(Ram value)
  164. {
  165. _isRamModalOpen = false;
  166. await UpdateServerUseCase.ExecuteAsync(Server.Name, value.Size, value.Mts, Server.Ipmi);
  167. Server = await GetServerUseCase.ExecuteAsync(Server.Name);
  168. }
  169. #endregion
  170. #region CPU
  171. bool _cpuModalOpen;
  172. int _editingCpuIndex;
  173. Cpu? _editingCpu;
  174. void OpenAddCpu()
  175. {
  176. _editingCpuIndex = -1;
  177. _editingCpu = null;
  178. _cpuModalOpen = true;
  179. }
  180. void OpenEditCpu(Cpu cpu)
  181. {
  182. _editingCpu = cpu;
  183. Server.Cpus ??= new();
  184. _editingCpuIndex = Server.Cpus.IndexOf(cpu);;
  185. _cpuModalOpen = true;
  186. }
  187. async Task HandleCpuSubmit(Cpu cpu)
  188. {
  189. Server.Cpus ??= new();
  190. if (_editingCpuIndex < 0)
  191. {
  192. await AddCpuUseCase.ExecuteAsync(Server.Name, cpu.Model, cpu.Cores, cpu.Threads);
  193. }
  194. else
  195. {
  196. await UpdateCpuUseCase.ExecuteAsync(Server.Name, _editingCpuIndex, cpu.Model, cpu.Cores, cpu.Threads);
  197. }
  198. Server = await GetServerUseCase.ExecuteAsync(Server.Name);
  199. }
  200. async Task HandleCpuDelete(Cpu cpu)
  201. {
  202. await RemoveCpuUseCase.ExecuteAsync(Server.Name, _editingCpuIndex);
  203. Server = await GetServerUseCase.ExecuteAsync(Server.Name);
  204. }
  205. #endregion
  206. #region Drives
  207. bool _driveModalOpen;
  208. int _editingDriveIndex;
  209. Drive? _editingDrive;
  210. void OpenAddDrive()
  211. {
  212. _editingDriveIndex = -1;
  213. _editingDrive = null;
  214. _driveModalOpen = true;
  215. }
  216. void OpenEditDrives(Drive drive)
  217. {
  218. _editingDrive = drive;
  219. Server.Drives ??= new();
  220. _editingDriveIndex = Server.Drives.IndexOf(drive);;
  221. _driveModalOpen = true;
  222. }
  223. async Task HandleDriveSubmit(Drive drive)
  224. {
  225. Server.Drives ??= new();
  226. if (_editingDriveIndex < 0)
  227. {
  228. await AddDriveUseCase.ExecuteAsync(Server.Name, drive.Type, drive.Size);
  229. }
  230. else
  231. {
  232. await UpdateDriveUseCase.ExecuteAsync(Server.Name, _editingDriveIndex, drive.Type, drive.Size);
  233. }
  234. Server = await GetServerUseCase.ExecuteAsync(Server.Name);
  235. StateHasChanged();
  236. }
  237. async Task HandleDriveDelete(Drive drive)
  238. {
  239. await RemoveDriveUseCase.ExecuteAsync(Server.Name, _editingDriveIndex);
  240. Server = await GetServerUseCase.ExecuteAsync(Server.Name);
  241. StateHasChanged();
  242. }
  243. #endregion
  244. }