disks.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <div class="ts-content">
  2. <div class="ts-container is-padded">
  3. <div id="disk-list">
  4. <div class="ts-box ts-content disk-info">
  5. <span class="ts-icon is-spinning is-circle-notch-icon"></span>
  6. <span class="has-start-padded-small" i18n>
  7. Loading...
  8. </span>
  9. </div>
  10. </div>
  11. <div class="ts-wrap is-end-aligned">
  12. <button id="refresh_disk_list_btn" class="ts-button is-start-icon has-top-spaced-large" >
  13. <span class="ts-icon is-rotate-icon"></span>
  14. <span i18n>
  15. Refresh
  16. // 重新整理
  17. </button>
  18. </div>
  19. </div>
  20. </div>
  21. <script>
  22. let hostDiskInfo = {
  23. "disks": []
  24. };
  25. function humanFileSize(size) {
  26. var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
  27. return +((size / Math.pow(1024, i)).toFixed(1)) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
  28. }
  29. $("#refresh_disk_list_btn").click(function(){
  30. $("#disk-list").html("");
  31. loadDiskInfo();
  32. msgbox(i18nc('disk_info_refreshed'));
  33. });
  34. function loadDiskInfo(){
  35. $("#disk-list").html(`
  36. <div class="ts-blankslate">
  37. <div class="header"><span class="ts-icon is-spinning is-spinner-icon"></span></div>
  38. </div>
  39. `);
  40. $.get("./api/info/list", function(data){
  41. if (data) {
  42. var disks = data;
  43. var diskList = $("#disk-list");
  44. diskList.empty();
  45. hostDiskInfo.disks = disks;
  46. for (var i = 0; i < disks.length; i++) {
  47. let disk = disks[i];
  48. let partitionDOM = "";
  49. let partitionTabs = "";
  50. //Render the partition tabs
  51. for (var j = 0; j < disk.partitions.length; j++) {
  52. let partition = disk.partitions[j];
  53. partitionTabs += `<a class="item ${j==0?"is-active":""}" data-tab="diskinfo_partition_${partition.name}">${partition.name}</a>`;
  54. }
  55. //Render the partition dom elements
  56. for (var j = 0; j < disk.partitions.length; j++) {
  57. let partition = disk.partitions[j];
  58. partitionDOM += `<div id="diskinfo_partition_${partition.name}" class="ts-box has-top-spaced-small">
  59. <div class="ts-content">
  60. <div class="ts-header">${partition.name}</div>
  61. <div class="ts-grid mobile:is-stacked">
  62. <div class="column is-fluid">
  63. <div class="ts-text is-description has-top-spaced-small">
  64. UUID: ${partition.uuid} <br>
  65. PartUUID: ${partition.partuuid} <br>
  66. PartLabel: ${partition.partlabel} <br>
  67. Path: ${partition.path} <br>
  68. Block Size: ${partition.blocksize} <br>
  69. Block Type: ${partition.blocktype} <br>
  70. File System Type: ${partition.fstype} <br>
  71. Mount Point: ${partition.mountpoint==undefined?"":partition.mountpoint} <br>
  72. </div>
  73. </div>
  74. <div class="column is-6-wide">
  75. <div class="ts-wrap is-middle-aligned has-top-spaced-small">
  76. <div class="ts-gauge is-small is-circular">
  77. <div class="bar" style="--value: ${parseInt(partition.used / partition.size * 100)}">
  78. <div class="text">${parseInt(partition.used / partition.size * 100)}%</div>
  79. </div>
  80. </div>
  81. <div>
  82. <div class="ts-text is-bold" i18n>
  83. Used Space
  84. // 已使用空間
  85. </div>
  86. ${humanFileSize(partition.used)} / ${humanFileSize(partition.size)}
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>`;
  93. }
  94. if (disk.partitions.length == 0){
  95. partitionTabs = `<a class="item is-disabled" i18n>
  96. No Partitions
  97. // 無分割區
  98. </a>`;
  99. }
  100. $(diskList).append(`<div class="ts-box ts-content has-top-spaced-small disk-info">
  101. <div class="ts-grid mobile:is-stacked">
  102. <div class="column is-fluid">
  103. <div class="ts-item">
  104. <div class="ts-header">${disk.model}</div>
  105. <div class="ts-text is-description has-top-spaced-small">
  106. ${disk.identifier}
  107. </div>
  108. <span>/dev/${disk.name}</span>
  109. </div>
  110. </div>
  111. <div class="column is-6-wide">
  112. <div class="ts-wrap is-middle-aligned has-top-spaced-small">
  113. <div class="ts-gauge is-small is-circular">
  114. <div class="bar" style="--value: ${parseInt(disk.used / disk.size * 100)}">
  115. <div class="text">${parseInt(disk.used / disk.size * 100)}%</div>
  116. </div>
  117. </div>
  118. <div>
  119. <div class="ts-text is-bold" i18n>
  120. Total Space Used
  121. // 總空間使用率
  122. </div>
  123. ${humanFileSize(disk.used)} / ${humanFileSize(disk.size)}
  124. </div>
  125. </div>
  126. </div>
  127. </div>
  128. <div class="has-top-spaced-big">
  129. <div class="ts-tab is-segmented">
  130. ${partitionTabs}
  131. </div>
  132. ${partitionDOM}
  133. </div>
  134. </div>`);
  135. }
  136. relocale();
  137. } else {
  138. console.error("Failed to load disk info: " + data.message);
  139. }
  140. });
  141. }
  142. loadDiskInfo();
  143. /* extern functions */
  144. // Get disk info by device path. Returns the disk or partition object.
  145. // return null if not found.
  146. function getDiskInfoDevicePath(devpath) {
  147. if (devpath.startsWith("/dev/")) {
  148. devpath = devpath.substring(5);
  149. }
  150. hostDiskInfo.disks.forEach(function(disk) {
  151. if (disk.name == devpath) {
  152. return disk;
  153. }
  154. disk.partitions.forEach(function(partition) {
  155. if (partition.path == devpath) {
  156. return partition;
  157. }
  158. });
  159. });
  160. return null;
  161. }
  162. </script>