ServiceCardComponent.razor 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. @using RackPeek.Domain.Resources.Services
  2. @using RackPeek.Domain.Resources.Services.UseCases
  3. @using RackPeek.Web.Components.Modals
  4. @inject UpdateServiceUseCase UpdateServiceUseCase
  5. @inject GetServiceUseCase GetServiceUseCase
  6. @inject DeleteServiceUseCase DeleteServiceUseCase
  7. <div class="border border-zinc-800 rounded p-4 bg-zinc-900">
  8. <div class="flex justify-between items-center mb-3">
  9. <NavLink href="@($"/resources/services/{Service.Name}")" class="block">
  10. <div class="text-zinc-100 hover:text-emerald-300">
  11. @Service.Name
  12. </div>
  13. </NavLink>
  14. <div class="flex gap-3 text-xs">
  15. @if (!_isEditing)
  16. {
  17. <button class="text-zinc-400 hover:text-zinc-200"
  18. @onclick="BeginEdit">
  19. Edit
  20. </button>
  21. <button
  22. class="text-xs text-red-400 hover:text-red-300 transition"
  23. title="Delete server"
  24. @onclick="ConfirmDelete">
  25. Delete
  26. </button>
  27. }
  28. else
  29. {
  30. <button class="text-emerald-400 hover:text-emerald-300"
  31. @onclick="Save">
  32. Save
  33. </button>
  34. <button class="text-zinc-500 hover:text-zinc-300"
  35. @onclick="Cancel">
  36. Cancel
  37. </button>
  38. }
  39. </div>
  40. </div>
  41. <div class="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
  42. <!-- IP -->
  43. <div>
  44. <div class="text-zinc-400 mb-1">IP</div>
  45. @if (_isEditing)
  46. {
  47. <input class="input"
  48. @bind="_edit.Ip"/>
  49. }
  50. else if (!string.IsNullOrWhiteSpace(Service.Network?.Ip))
  51. {
  52. <div class="text-zinc-300">@Service.Network!.Ip</div>
  53. }
  54. </div>
  55. <!-- Port -->
  56. <div>
  57. <div class="text-zinc-400 mb-1">Port</div>
  58. @if (_isEditing)
  59. {
  60. <input type="number"
  61. class="input"
  62. @bind="_edit.Port"/>
  63. }
  64. else if (Service.Network?.Port.HasValue == true)
  65. {
  66. <div class="text-zinc-300">@Service.Network.Port</div>
  67. }
  68. </div>
  69. <!-- Protocol -->
  70. <div>
  71. <div class="text-zinc-400 mb-1">Protocol</div>
  72. @if (_isEditing)
  73. {
  74. <input class="input"
  75. @bind="_edit.Protocol"/>
  76. }
  77. else if (!string.IsNullOrWhiteSpace(Service.Network?.Protocol))
  78. {
  79. <div class="text-zinc-300">@Service.Network!.Protocol</div>
  80. }
  81. </div>
  82. <!-- URL -->
  83. <div>
  84. <div class="text-zinc-400 mb-1">URL</div>
  85. @if (_isEditing)
  86. {
  87. <input class="input"
  88. @bind="_edit.Url"/>
  89. }
  90. else if (!string.IsNullOrWhiteSpace(Service.Network?.Url))
  91. {
  92. <a href="@Service.Network!.Url"
  93. target="_blank"
  94. rel="noopener noreferrer"
  95. class="text-emerald-400 hover:underline break-all">
  96. @Service.Network.Url
  97. </a>
  98. }
  99. </div>
  100. <!-- Runs On -->
  101. <div>
  102. <div class="text-zinc-400 mb-1">Runs On</div>
  103. @if (_isEditing)
  104. {
  105. <button
  106. class="hover:text-emerald-400"
  107. title="Edit Runs On"
  108. @onclick="() => _selectParentOpen = true">
  109. @if (!string.IsNullOrWhiteSpace(Service.RunsOn))
  110. {
  111. @($"{Service.RunsOn} +")
  112. }
  113. else
  114. {
  115. @("Edit parent")
  116. }
  117. </button>
  118. }
  119. else if (!string.IsNullOrWhiteSpace(Service.RunsOn))
  120. {
  121. <NavLink href="@($"/resources/systems/{Service.RunsOn}")"
  122. class="text-emerald-400">
  123. @Service.RunsOn
  124. </NavLink>
  125. }
  126. </div>
  127. </div>
  128. </div>
  129. <SystemSelectionModal
  130. IsOpen="@_selectParentOpen"
  131. IsOpenChanged="v => _selectParentOpen = v"
  132. Title="Select a parent"
  133. Value="@SelectedParentName"
  134. OnAccept="HandleParentSelected"/>
  135. <ConfirmModal
  136. IsOpen="_confirmDeleteOpen"
  137. IsOpenChanged="v => _confirmDeleteOpen = v"
  138. Title="Delete server"
  139. ConfirmText="Delete"
  140. ConfirmClass="bg-red-600 hover:bg-red-500"
  141. OnConfirm="DeleteServer">
  142. Are you sure you want to delete <strong>@Service.Name</strong>?
  143. </ConfirmModal>
  144. @code {
  145. [Parameter] [EditorRequired] public Service Service { get; set; } = default!;
  146. [Parameter] public EventCallback<ServiceEditModel> OnSave { get; set; }
  147. private bool _isEditing;
  148. private ServiceEditModel _edit = new();
  149. void BeginEdit()
  150. {
  151. _edit = ServiceEditModel.From(Service);
  152. _isEditing = true;
  153. }
  154. async Task Save()
  155. {
  156. _isEditing = false;
  157. await OnSave.InvokeAsync(_edit);
  158. }
  159. void Cancel()
  160. {
  161. _isEditing = false;
  162. }
  163. bool _selectParentOpen;
  164. string? SelectedParentName;
  165. async Task HandleParentSelected(string? name)
  166. {
  167. SelectedParentName = name;
  168. await UpdateServiceUseCase.ExecuteAsync(
  169. Service.Name,
  170. Service.Network?.Ip,
  171. Service.Network?.Port,
  172. Service.Network?.Protocol,
  173. Service.Network?.Url,
  174. name);
  175. Service = await GetServiceUseCase.ExecuteAsync(Service.Name);
  176. _edit = ServiceEditModel.From(Service);
  177. }
  178. }
  179. <ConfirmModal
  180. IsOpen="_confirmDeleteOpen"
  181. IsOpenChanged="v => _confirmDeleteOpen = v"
  182. Title="Delete service"
  183. ConfirmText="Delete"
  184. ConfirmClass="bg-red-600 hover:bg-red-500"
  185. OnConfirm="DeleteServer">
  186. Are you sure you want to delete <strong>@Service.Name</strong>?
  187. <br/>
  188. </ConfirmModal>
  189. @code {
  190. private bool _confirmDeleteOpen;
  191. [Parameter] public EventCallback<string> OnDeleted { get; set; }
  192. void ConfirmDelete()
  193. {
  194. _confirmDeleteOpen = true;
  195. }
  196. async Task DeleteServer()
  197. {
  198. _confirmDeleteOpen = false;
  199. await DeleteServiceUseCase.ExecuteAsync(Service.Name);
  200. if (OnDeleted.HasDelegate)
  201. await OnDeleted.InvokeAsync(Service.Name);
  202. }
  203. }