containerCard.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. export const containerCard = (data) => {
  2. let { name, service, state, external_port, internal_port, ports, link } = data;
  3. let wrapped = name;
  4. let disable = "";
  5. let chartName = name.replace(/-/g, '');
  6. // shorten long names
  7. if (name.length > 13) { wrapped = name.slice(0, 10) + '...'; }
  8. // disable buttons for dweebui
  9. if (name.startsWith('dweebui')) { disable = 'disabled=""'; }
  10. if ( external_port == undefined ) { external_port = 0; }
  11. if ( internal_port == undefined ) { internal_port = 0; }
  12. let state_indicator = 'green';
  13. if (state == 'exited') {
  14. state = 'stopped';
  15. state_indicator = 'red';
  16. } else if (state == 'paused') {
  17. state_indicator = 'orange';
  18. }
  19. let noChart = 'hx-swap="none"';
  20. if (state == 'running') { noChart = ''; }
  21. let ports_data = [];
  22. if (ports) {
  23. ports_data = ports;
  24. } else {
  25. for (let i = 0; i < 12; i++) {
  26. let port_check = "checked";
  27. let external = i;
  28. let internal = i;
  29. let protocol = "tcp";
  30. ports_data.push({
  31. check: port_check,
  32. external: external,
  33. internal: internal,
  34. protocol: protocol
  35. });
  36. }
  37. }
  38. return `
  39. <div class="col-sm-6 col-lg-3 pt-1">
  40. <div class="card">
  41. <div class="card-body">
  42. <div class="card-stamp card-stamp-sm">
  43. <img width="100px" src="https://raw.githubusercontent.com/lllllllillllllillll/DweebUI-Icons/main/${service}.png" onerror="this.onerror=null;this.src='https://raw.githubusercontent.com/lllllllillllllillll/DweebUI-Icons/main/docker.png';"></img>
  44. </div>
  45. <div class="d-flex align-items-center">
  46. <div class="subheader text-yellow">${external_port}:${internal_port}</div>
  47. <div class="ms-auto lh-1">
  48. <div class="card-actions btn-actions">
  49. <div class="card-actions btn-actions">
  50. <button class="btn-action" title="Start" data-hx-post="/start" data-hx-trigger="click" data-hx-target="#${name}state" name="${name}" id="${state}" ${disable}><!-- player-play -->
  51. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-play" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 4v16l13 -8z"></path></svg>
  52. </button>
  53. <button class="btn-action" title="Stop" data-hx-post="/stop" data-hx-trigger="click" data-hx-target="#${name}state" name="${name}" id="${state}" ${disable}><!-- player-stop -->
  54. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-stop" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 5m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path></svg>
  55. </button>
  56. <button class="btn-action" title="Pause" data-hx-post="/pause" data-hx-trigger="click" data-hx-target="#${name}state" name="${name}" id="${state}" ${disable}><!-- player-pause -->
  57. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-pause" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path><path d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path></svg>
  58. </button>
  59. <button class="btn-action" title="Restart" data-hx-post="/restart" data-hx-trigger="click" data-hx-target="#${name}state" name="${name}" id="${state}" ${disable}><!-- reload -->
  60. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-reload" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M19.933 13.041a8 8 0 1 1 -9.925 -8.788c3.899 -1 7.935 1.007 9.425 4.747"></path><path d="M20 4v5h-5"></path></svg>
  61. </button>
  62. <div class="dropdown">
  63. <a href="#" class="btn-action dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  64. <svg xmlns="http://www.w3.org/2000/svg" class="" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><circle cx="12" cy="12" r="1"></circle><circle cx="12" cy="19" r="1"></circle><circle cx="12" cy="5" r="1"></circle></svg>
  65. </a>
  66. <div class="dropdown-menu dropdown-menu-end">
  67. <button class="dropdown-item text-secondary" name="${name}" data-hx-get="/modal" data-hx-target="#modals-here" data-hx-trigger="click" data-bs-toggle="modal" data-bs-target="#modals-here">Details</button>
  68. <button class="dropdown-item text-secondary" name="${name}" id="logs" data-hx-get="/logs" data-hx-target="#logView" data-bs-toggle="modal" data-bs-target="#log_view">Logs</button>
  69. <button class="dropdown-item text-secondary" name="${name}" id="edit">Edit</button>
  70. <button class="dropdown-item text-primary" name="${name}" id="update" disabled="">Update</button>
  71. <button class="dropdown-item text-danger" name="${name}" id="remove" data-bs-toggle="modal" data-bs-target="#${name}_uninstall_modal" href="#">Remove</button>
  72. </div>
  73. </div>
  74. <div class="dropdown">
  75. <a href="#" class="btn-action dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  76. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-eye" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"/> <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" /> <path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" /> </svg>
  77. </a>
  78. <div class="dropdown-menu dropdown-menu-end">
  79. <button class="dropdown-item text-secondary" data-hx-post="/hide" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="hide" value="hide">Hide</button>
  80. <button class="dropdown-item text-secondary" data-hx-post="/reset" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="reset" value="reset">Reset View</button>
  81. <button class="dropdown-item text-secondary" name="${name}" id="permissions" data-hx-get="/modal" data-hx-target="#modals-here" data-hx-trigger="click" data-bs-toggle="modal" data-bs-target="#modals-here">Permissions</button>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. <div class="d-flex align-items-baseline">
  89. <div class="h1 me-2" title="${name}" style="margin-bottom: 0;">
  90. <a href="http://${link}:${external_port}" target="_blank">
  91. ${wrapped}
  92. </a>
  93. </div>
  94. <div class="ms-auto">
  95. <label id="${name}state">
  96. <span class="text-${state_indicator} align-items-center lh-1">
  97. <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-point-filled" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 7a5 5 0 1 1 -4.995 5.217l-.005 -.217l.005 -.217a5 5 0 0 1 4.995 -4.783z" stroke-width="0" fill="currentColor"></path></svg>
  98. ${state}
  99. </span>
  100. </label>
  101. </div>
  102. </div>
  103. <script>
  104. var ${chartName}chart = new ApexCharts(document.querySelector("#${chartName}_chart"), options);
  105. </script>
  106. <div class="chart-sm">
  107. <div id="${chartName}_chart" data-hx-trigger="load, every 2s" data-hx-get="/chart" name="${chartName}" ${noChart}>
  108. <script>
  109. ${chartName}chart.render();
  110. </script>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. </div>
  116. <div class="modal modal-blur fade" id="${name}_uninstall_modal" tabindex="-1" style="display: none;" aria-hidden="true">
  117. <div class="modal-dialog modal-sm modal-dialog-centered" role="document">
  118. <div class="modal-content">
  119. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  120. <div class="modal-status bg-danger"></div>
  121. <div class="modal-body text-center py-3">
  122. <svg xmlns="http://www.w3.org/2000/svg" class="icon mb-2 text-danger icon-lg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 9v2m0 4v.01"></path><path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path></svg>
  123. <h3>Remove ${name}?</h3>
  124. <form action="/uninstall" id="${name}_uninstall" method="POST">
  125. <input type="text" class="form-control" name="service_name" value="${name}" hidden/>
  126. <div class="mb-3"> </div>
  127. <div class="mb-2">
  128. <div class="divide-y">
  129. <div class="row">
  130. <div class="col-9">
  131. <label class="row text-start">
  132. <span class="col">Remove Volumes</span>
  133. </label>
  134. </div>
  135. <div class="col-3">
  136. <label class="form-check form-check-single form-switch text-end">
  137. <input class="form-check-input" type="checkbox" name="remove_volumes" disabled="">
  138. </label>
  139. </div>
  140. </div>
  141. <div class="row">
  142. <div class="col-9">
  143. <label class="row text-start">
  144. <span class="col">
  145. Remove Image
  146. </span>
  147. </label>
  148. </div>
  149. <div class="col-3">
  150. <label class="form-check form-check-single form-switch text-end">
  151. <input class="form-check-input" type="checkbox" name="remove_image" disabled="">
  152. </label>
  153. </div>
  154. </div>
  155. <div class="row">
  156. <div class="col-9">
  157. <label class="row text-start">
  158. <span class="col">
  159. Remove Backups
  160. </span>
  161. </label>
  162. </div>
  163. <div class="col-3">
  164. <label class="form-check form-check-single form-switch text-end">
  165. <input class="form-check-input" type="checkbox" name="remove_backups" disabled="">
  166. </label>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. <div class="mt-1"> </div>
  172. <div class="text-muted">Enter "Yes" below to remove the container.</div>
  173. <input type="text" class="form-control mb-2" name="confirm" autocomplete="off">
  174. </form>
  175. </div>
  176. <div class="modal-footer">
  177. <div class="w-100">
  178. <div class="row">
  179. <div class="col">
  180. <a href="#" class="btn w-100" data-bs-dismiss="modal">
  181. Cancel
  182. </a>
  183. </div>
  184. <div class="col">
  185. <input type="submit" form="${name}_uninstall" class="btn btn-danger w-100" value="Uninstall"/>
  186. </div>
  187. </div>
  188. </div>
  189. </div>
  190. </div>
  191. </div>
  192. </div>
  193. <div class="modal modal-blur fade" id="${name}_permissions" tabindex="-1" style="display: none;" aria-hidden="true">
  194. <div class="modal-dialog modal-sm modal-dialog-centered" role="document">
  195. <div class="modal-content">
  196. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  197. <div class="modal-status bg-cyan"></div>
  198. <div class="modal-body text-center py-3">
  199. <h3>${name} permissions</h3>
  200. <form action="#" id="${name}_permissions" method="POST">
  201. <input type="text" class="form-control" name="service_name" value="${name}" hidden/>
  202. <div class="mb-2">
  203. <div class="divide-y">
  204. <div class="row">
  205. <div class="col-9">
  206. <div class="d-flex align-items-center">
  207. User:
  208. <select class="form-select ms-2">
  209. <option value="john_doe" selected hidden>John Doe</option>
  210. <option value="john_doe">John Doe</option>
  211. <option value="jane_doe">Jane Doe</option>
  212. </select>
  213. </div>
  214. </div>
  215. </div>
  216. <div class="row">
  217. <div class="col-9">
  218. <label class="row text-start">
  219. <span class="col">
  220. View
  221. </span>
  222. </label>
  223. </div>
  224. <div class="col-3">
  225. <label class="form-check form-check-single form-switch text-end">
  226. <input class="form-check-input" type="checkbox" name="remove_image">
  227. </label>
  228. </div>
  229. </div>
  230. <div class="row">
  231. <div class="col-9">
  232. <label class="row text-start">
  233. <span class="col">
  234. Uninstall
  235. </span>
  236. </label>
  237. </div>
  238. <div class="col-3">
  239. <label class="form-check form-check-single form-switch text-end">
  240. <input class="form-check-input" type="checkbox" name="remove_image">
  241. </label>
  242. </div>
  243. </div>
  244. <div class="row">
  245. <div class="col-9">
  246. <label class="row text-start">
  247. <span class="col">
  248. Edit
  249. </span>
  250. </label>
  251. </div>
  252. <div class="col-3">
  253. <label class="form-check form-check-single form-switch text-end">
  254. <input class="form-check-input" type="checkbox" name="remove_backups">
  255. </label>
  256. </div>
  257. </div>
  258. <div class="row">
  259. <div class="col-9">
  260. <label class="row text-start">
  261. <span class="col">
  262. Upgrade
  263. </span>
  264. </label>
  265. </div>
  266. <div class="col-3">
  267. <label class="form-check form-check-single form-switch text-end">
  268. <input class="form-check-input" type="checkbox" name="remove_backups">
  269. </label>
  270. </div>
  271. </div>
  272. </div>
  273. </div>
  274. <div class="mt-1"> </div>
  275. </form>
  276. </div>
  277. <div class="modal-footer">
  278. <div class="w-100">
  279. <div class="row">
  280. <div class="col">
  281. <a href="#" class="btn w-100" data-bs-dismiss="modal">
  282. Cancel
  283. </a>
  284. </div>
  285. <div class="col">
  286. <input type="submit" form="${name}_permissions" class="btn btn-primary w-100" value="Update"/>
  287. </div>
  288. </div>
  289. </div>
  290. </div>
  291. </div>
  292. </div>
  293. </div>`;
  294. }