disks.html 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. $.get("./api/info/list", function(data){
  36. if (data) {
  37. var disks = data;
  38. var diskList = $("#disk-list");
  39. diskList.empty();
  40. hostDiskInfo.disks = disks;
  41. for (var i = 0; i < disks.length; i++) {
  42. let disk = disks[i];
  43. let partitionDOM = "";
  44. let partitionTabs = "";
  45. //Render the partition tabs
  46. for (var j = 0; j < disk.partitions.length; j++) {
  47. let partition = disk.partitions[j];
  48. partitionTabs += `<a class="item ${j==0?"is-active":""}" data-tab="diskinfo_partition_${partition.name}">${partition.name}</a>`;
  49. }
  50. //Render the partition dom elements
  51. for (var j = 0; j < disk.partitions.length; j++) {
  52. let partition = disk.partitions[j];
  53. partitionDOM += `<div id="diskinfo_partition_${partition.name}" class="ts-box has-top-spaced-small">
  54. <div class="ts-content">
  55. <div class="ts-header">${partition.name}</div>
  56. <div class="ts-grid mobile:is-stacked">
  57. <div class="column is-fluid">
  58. <div class="ts-text is-description has-top-spaced-small">
  59. UUID: ${partition.uuid} <br>
  60. PartUUID: ${partition.partuuid} <br>
  61. PartLabel: ${partition.partlabel} <br>
  62. Path: ${partition.path} <br>
  63. Block Size: ${partition.blocksize} <br>
  64. Block Type: ${partition.blocktype} <br>
  65. File System Type: ${partition.fstype} <br>
  66. Mount Point: ${partition.mountpoint==undefined?"":partition.mountpoint} <br>
  67. </div>
  68. </div>
  69. <div class="column is-6-wide">
  70. <div class="ts-wrap is-middle-aligned has-top-spaced-small">
  71. <div class="ts-gauge is-small is-circular">
  72. <div class="bar" style="--value: ${parseInt(partition.used / partition.size * 100)}">
  73. <div class="text">${parseInt(partition.used / partition.size * 100)}%</div>
  74. </div>
  75. </div>
  76. <div>
  77. <div class="ts-text is-bold" i18n>
  78. Used Space
  79. // 已使用空間
  80. </div>
  81. ${humanFileSize(partition.used)} / ${humanFileSize(partition.size)}
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. </div>`;
  88. }
  89. if (disk.partitions.length == 0){
  90. partitionTabs = `<a class="item is-disabled" i18n>
  91. No Partitions
  92. // 無分割區
  93. </a>`;
  94. }
  95. $(diskList).append(`<div class="ts-box ts-content has-top-spaced-small disk-info">
  96. <div class="ts-grid mobile:is-stacked">
  97. <div class="column is-fluid">
  98. <div class="ts-item">
  99. <div class="ts-header">${disk.model}</div>
  100. <div class="ts-text is-description has-top-spaced-small">
  101. ${disk.identifier}
  102. </div>
  103. <span>/dev/${disk.name}</span>
  104. </div>
  105. </div>
  106. <div class="column is-6-wide">
  107. <div class="ts-wrap is-middle-aligned has-top-spaced-small">
  108. <div class="ts-gauge is-small is-circular">
  109. <div class="bar" style="--value: ${parseInt(disk.used / disk.size * 100)}">
  110. <div class="text">${parseInt(disk.used / disk.size * 100)}%</div>
  111. </div>
  112. </div>
  113. <div>
  114. <div class="ts-text is-bold" i18n>
  115. Total Space Used
  116. // 總空間使用率
  117. </div>
  118. ${humanFileSize(disk.used)} / ${humanFileSize(disk.size)}
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. <div class="has-top-spaced-big">
  124. <div class="ts-tab is-segmented">
  125. ${partitionTabs}
  126. </div>
  127. ${partitionDOM}
  128. </div>
  129. </div>`);
  130. }
  131. relocale();
  132. } else {
  133. console.error("Failed to load disk info: " + data.message);
  134. }
  135. });
  136. }
  137. loadDiskInfo();
  138. /* extern functions */
  139. // Get disk info by device path. Returns the disk or partition object.
  140. // return null if not found.
  141. function getDiskInfoDevicePath(devpath) {
  142. if (devpath.startsWith("/dev/")) {
  143. devpath = devpath.substring(5);
  144. }
  145. hostDiskInfo.disks.forEach(function(disk) {
  146. console.log(disk.name, devpath);
  147. if (disk.name == devpath) {
  148. return disk;
  149. }
  150. disk.partitions.forEach(function(partition) {
  151. if (partition.path == devpath) {
  152. return partition;
  153. }
  154. });
  155. });
  156. return null;
  157. }
  158. </script>