cluster_collections_templ.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // Code generated by templ - DO NOT EDIT.
  2. // templ: version: v0.3.906
  3. package app
  4. //lint:file-ignore SA4006 This context is only used if a nested component is present.
  5. import "github.com/a-h/templ"
  6. import templruntime "github.com/a-h/templ/runtime"
  7. import (
  8. "fmt"
  9. "github.com/seaweedfs/seaweedfs/weed/admin/dash"
  10. )
  11. func ClusterCollections(data dash.ClusterCollectionsData) templ.Component {
  12. return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
  13. templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
  14. if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
  15. return templ_7745c5c3_CtxErr
  16. }
  17. templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
  18. if !templ_7745c5c3_IsBuffer {
  19. defer func() {
  20. templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
  21. if templ_7745c5c3_Err == nil {
  22. templ_7745c5c3_Err = templ_7745c5c3_BufErr
  23. }
  24. }()
  25. }
  26. ctx = templ.InitializeContext(ctx)
  27. templ_7745c5c3_Var1 := templ.GetChildren(ctx)
  28. if templ_7745c5c3_Var1 == nil {
  29. templ_7745c5c3_Var1 = templ.NopComponent
  30. }
  31. ctx = templ.ClearChildren(ctx)
  32. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom\"><h1 class=\"h2\"><i class=\"fas fa-layer-group me-2\"></i>Cluster Collections</h1><div class=\"btn-toolbar mb-2 mb-md-0\"><div class=\"btn-group me-2\"><button type=\"button\" class=\"btn btn-sm btn-outline-primary\" onclick=\"exportCollections()\"><i class=\"fas fa-download me-1\"></i>Export</button></div></div></div><div id=\"collections-content\"><!-- Summary Cards --><div class=\"row mb-4\"><div class=\"col-xl-2 col-lg-3 col-md-4 col-sm-6 mb-4\"><div class=\"card border-left-primary shadow h-100 py-2\"><div class=\"card-body\"><div class=\"row no-gutters align-items-center\"><div class=\"col mr-2\"><div class=\"text-xs font-weight-bold text-primary text-uppercase mb-1\">Total Collections</div><div class=\"h5 mb-0 font-weight-bold text-gray-800\">")
  33. if templ_7745c5c3_Err != nil {
  34. return templ_7745c5c3_Err
  35. }
  36. var templ_7745c5c3_Var2 string
  37. templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalCollections))
  38. if templ_7745c5c3_Err != nil {
  39. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 34, Col: 77}
  40. }
  41. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
  42. if templ_7745c5c3_Err != nil {
  43. return templ_7745c5c3_Err
  44. }
  45. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</div></div><div class=\"col-auto\"><i class=\"fas fa-layer-group fa-2x text-gray-300\"></i></div></div></div></div></div><div class=\"col-xl-2 col-lg-3 col-md-4 col-sm-6 mb-4\"><div class=\"card border-left-info shadow h-100 py-2\"><div class=\"card-body\"><div class=\"row no-gutters align-items-center\"><div class=\"col mr-2\"><div class=\"text-xs font-weight-bold text-info text-uppercase mb-1\">Regular Volumes</div><div class=\"h5 mb-0 font-weight-bold text-gray-800\">")
  46. if templ_7745c5c3_Err != nil {
  47. return templ_7745c5c3_Err
  48. }
  49. var templ_7745c5c3_Var3 string
  50. templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalVolumes))
  51. if templ_7745c5c3_Err != nil {
  52. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 54, Col: 73}
  53. }
  54. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
  55. if templ_7745c5c3_Err != nil {
  56. return templ_7745c5c3_Err
  57. }
  58. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div></div><div class=\"col-auto\"><i class=\"fas fa-database fa-2x text-gray-300\"></i></div></div></div></div></div><div class=\"col-xl-2 col-lg-3 col-md-4 col-sm-6 mb-4\"><div class=\"card border-left-success shadow h-100 py-2\"><div class=\"card-body\"><div class=\"row no-gutters align-items-center\"><div class=\"col mr-2\"><div class=\"text-xs font-weight-bold text-success text-uppercase mb-1\">EC Volumes</div><div class=\"h5 mb-0 font-weight-bold text-gray-800\">")
  59. if templ_7745c5c3_Err != nil {
  60. return templ_7745c5c3_Err
  61. }
  62. var templ_7745c5c3_Var4 string
  63. templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalEcVolumes))
  64. if templ_7745c5c3_Err != nil {
  65. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 74, Col: 75}
  66. }
  67. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
  68. if templ_7745c5c3_Err != nil {
  69. return templ_7745c5c3_Err
  70. }
  71. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div></div><div class=\"col-auto\"><i class=\"fas fa-th-large fa-2x text-gray-300\"></i></div></div></div></div></div><div class=\"col-xl-2 col-lg-3 col-md-4 col-sm-6 mb-4\"><div class=\"card border-left-warning shadow h-100 py-2\"><div class=\"card-body\"><div class=\"row no-gutters align-items-center\"><div class=\"col mr-2\"><div class=\"text-xs font-weight-bold text-warning text-uppercase mb-1\">Total Files</div><div class=\"h5 mb-0 font-weight-bold text-gray-800\">")
  72. if templ_7745c5c3_Err != nil {
  73. return templ_7745c5c3_Err
  74. }
  75. var templ_7745c5c3_Var5 string
  76. templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalFiles))
  77. if templ_7745c5c3_Err != nil {
  78. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 94, Col: 71}
  79. }
  80. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
  81. if templ_7745c5c3_Err != nil {
  82. return templ_7745c5c3_Err
  83. }
  84. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div></div><div class=\"col-auto\"><i class=\"fas fa-file fa-2x text-gray-300\"></i></div></div></div></div></div><div class=\"col-xl-2 col-lg-3 col-md-4 col-sm-6 mb-4\"><div class=\"card border-left-secondary shadow h-100 py-2\"><div class=\"card-body\"><div class=\"row no-gutters align-items-center\"><div class=\"col mr-2\"><div class=\"text-xs font-weight-bold text-secondary text-uppercase mb-1\">Total Storage Size (Logical)</div><div class=\"h5 mb-0 font-weight-bold text-gray-800\">")
  85. if templ_7745c5c3_Err != nil {
  86. return templ_7745c5c3_Err
  87. }
  88. var templ_7745c5c3_Var6 string
  89. templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(data.TotalSize))
  90. if templ_7745c5c3_Err != nil {
  91. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 114, Col: 64}
  92. }
  93. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
  94. if templ_7745c5c3_Err != nil {
  95. return templ_7745c5c3_Err
  96. }
  97. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</div></div><div class=\"col-auto\"><i class=\"fas fa-hdd fa-2x text-gray-300\"></i></div></div></div></div></div></div><!-- Collections Table --><div class=\"card shadow mb-4\"><div class=\"card-header py-3\"><h6 class=\"m-0 font-weight-bold text-primary\"><i class=\"fas fa-layer-group me-2\"></i>Collection Details</h6></div><div class=\"card-body\">")
  98. if templ_7745c5c3_Err != nil {
  99. return templ_7745c5c3_Err
  100. }
  101. if len(data.Collections) > 0 {
  102. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<div class=\"table-responsive\"><table class=\"table table-hover\" id=\"collectionsTable\"><thead><tr><th>Collection Name</th><th>Regular Volumes</th><th>EC Volumes</th><th>Files</th><th>Size (Logical)</th><th>Disk Types</th><th>Actions</th></tr></thead> <tbody>")
  103. if templ_7745c5c3_Err != nil {
  104. return templ_7745c5c3_Err
  105. }
  106. for _, collection := range data.Collections {
  107. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<tr><td><a href=\"")
  108. if templ_7745c5c3_Err != nil {
  109. return templ_7745c5c3_Err
  110. }
  111. var templ_7745c5c3_Var7 templ.SafeURL
  112. templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/cluster/collections/%s", collection.Name)))
  113. if templ_7745c5c3_Err != nil {
  114. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 152, Col: 123}
  115. }
  116. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
  117. if templ_7745c5c3_Err != nil {
  118. return templ_7745c5c3_Err
  119. }
  120. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" class=\"text-decoration-none\"><strong>")
  121. if templ_7745c5c3_Err != nil {
  122. return templ_7745c5c3_Err
  123. }
  124. var templ_7745c5c3_Var8 string
  125. templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name)
  126. if templ_7745c5c3_Err != nil {
  127. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 153, Col: 68}
  128. }
  129. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
  130. if templ_7745c5c3_Err != nil {
  131. return templ_7745c5c3_Err
  132. }
  133. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</strong></a></td><td><a href=\"")
  134. if templ_7745c5c3_Err != nil {
  135. return templ_7745c5c3_Err
  136. }
  137. var templ_7745c5c3_Var9 templ.SafeURL
  138. templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/cluster/volumes?collection=%s", collection.Name)))
  139. if templ_7745c5c3_Err != nil {
  140. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 157, Col: 130}
  141. }
  142. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
  143. if templ_7745c5c3_Err != nil {
  144. return templ_7745c5c3_Err
  145. }
  146. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" class=\"text-decoration-none\"><div class=\"d-flex align-items-center\"><i class=\"fas fa-database me-2 text-muted\"></i> ")
  147. if templ_7745c5c3_Err != nil {
  148. return templ_7745c5c3_Err
  149. }
  150. if collection.VolumeCount > 0 {
  151. var templ_7745c5c3_Var10 string
  152. templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.VolumeCount))
  153. if templ_7745c5c3_Err != nil {
  154. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 161, Col: 94}
  155. }
  156. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
  157. if templ_7745c5c3_Err != nil {
  158. return templ_7745c5c3_Err
  159. }
  160. } else {
  161. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<span class=\"text-muted\">0</span>")
  162. if templ_7745c5c3_Err != nil {
  163. return templ_7745c5c3_Err
  164. }
  165. }
  166. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</div></a></td><td><a href=\"")
  167. if templ_7745c5c3_Err != nil {
  168. return templ_7745c5c3_Err
  169. }
  170. var templ_7745c5c3_Var11 templ.SafeURL
  171. templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/cluster/ec-shards?collection=%s", collection.Name)))
  172. if templ_7745c5c3_Err != nil {
  173. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 169, Col: 132}
  174. }
  175. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
  176. if templ_7745c5c3_Err != nil {
  177. return templ_7745c5c3_Err
  178. }
  179. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" class=\"text-decoration-none\"><div class=\"d-flex align-items-center\"><i class=\"fas fa-th-large me-2 text-muted\"></i> ")
  180. if templ_7745c5c3_Err != nil {
  181. return templ_7745c5c3_Err
  182. }
  183. if collection.EcVolumeCount > 0 {
  184. var templ_7745c5c3_Var12 string
  185. templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.EcVolumeCount))
  186. if templ_7745c5c3_Err != nil {
  187. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 173, Col: 96}
  188. }
  189. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
  190. if templ_7745c5c3_Err != nil {
  191. return templ_7745c5c3_Err
  192. }
  193. } else {
  194. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<span class=\"text-muted\">0</span>")
  195. if templ_7745c5c3_Err != nil {
  196. return templ_7745c5c3_Err
  197. }
  198. }
  199. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</div></a></td><td><div class=\"d-flex align-items-center\"><i class=\"fas fa-file me-2 text-muted\"></i> ")
  200. if templ_7745c5c3_Err != nil {
  201. return templ_7745c5c3_Err
  202. }
  203. var templ_7745c5c3_Var13 string
  204. templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.FileCount))
  205. if templ_7745c5c3_Err != nil {
  206. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 183, Col: 88}
  207. }
  208. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
  209. if templ_7745c5c3_Err != nil {
  210. return templ_7745c5c3_Err
  211. }
  212. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div></td><td><div class=\"d-flex align-items-center\"><i class=\"fas fa-hdd me-2 text-muted\"></i> ")
  213. if templ_7745c5c3_Err != nil {
  214. return templ_7745c5c3_Err
  215. }
  216. var templ_7745c5c3_Var14 string
  217. templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(collection.TotalSize))
  218. if templ_7745c5c3_Err != nil {
  219. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 189, Col: 82}
  220. }
  221. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
  222. if templ_7745c5c3_Err != nil {
  223. return templ_7745c5c3_Err
  224. }
  225. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</div></td><td>")
  226. if templ_7745c5c3_Err != nil {
  227. return templ_7745c5c3_Err
  228. }
  229. for i, diskType := range collection.DiskTypes {
  230. if i > 0 {
  231. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<span class=\"me-1\"></span>")
  232. if templ_7745c5c3_Err != nil {
  233. return templ_7745c5c3_Err
  234. }
  235. }
  236. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ")
  237. if templ_7745c5c3_Err != nil {
  238. return templ_7745c5c3_Err
  239. }
  240. var templ_7745c5c3_Var15 = []any{fmt.Sprintf("badge bg-%s me-1", getDiskTypeColor(diskType))}
  241. templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
  242. if templ_7745c5c3_Err != nil {
  243. return templ_7745c5c3_Err
  244. }
  245. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<span class=\"")
  246. if templ_7745c5c3_Err != nil {
  247. return templ_7745c5c3_Err
  248. }
  249. var templ_7745c5c3_Var16 string
  250. templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String())
  251. if templ_7745c5c3_Err != nil {
  252. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 1, Col: 0}
  253. }
  254. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
  255. if templ_7745c5c3_Err != nil {
  256. return templ_7745c5c3_Err
  257. }
  258. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\">")
  259. if templ_7745c5c3_Err != nil {
  260. return templ_7745c5c3_Err
  261. }
  262. var templ_7745c5c3_Var17 string
  263. templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(diskType)
  264. if templ_7745c5c3_Err != nil {
  265. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 197, Col: 131}
  266. }
  267. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
  268. if templ_7745c5c3_Err != nil {
  269. return templ_7745c5c3_Err
  270. }
  271. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span> ")
  272. if templ_7745c5c3_Err != nil {
  273. return templ_7745c5c3_Err
  274. }
  275. }
  276. if len(collection.DiskTypes) == 0 {
  277. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<span class=\"text-muted\">Unknown</span>")
  278. if templ_7745c5c3_Err != nil {
  279. return templ_7745c5c3_Err
  280. }
  281. }
  282. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "</td><td><button type=\"button\" class=\"btn btn-outline-primary btn-sm\" title=\"View Details\" data-action=\"view-details\" data-name=\"")
  283. if templ_7745c5c3_Err != nil {
  284. return templ_7745c5c3_Err
  285. }
  286. var templ_7745c5c3_Var18 string
  287. templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name)
  288. if templ_7745c5c3_Err != nil {
  289. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 208, Col: 78}
  290. }
  291. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
  292. if templ_7745c5c3_Err != nil {
  293. return templ_7745c5c3_Err
  294. }
  295. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\" data-datacenter=\"")
  296. if templ_7745c5c3_Err != nil {
  297. return templ_7745c5c3_Err
  298. }
  299. var templ_7745c5c3_Var19 string
  300. templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(collection.DataCenter)
  301. if templ_7745c5c3_Err != nil {
  302. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 209, Col: 90}
  303. }
  304. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
  305. if templ_7745c5c3_Err != nil {
  306. return templ_7745c5c3_Err
  307. }
  308. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\" data-volume-count=\"")
  309. if templ_7745c5c3_Err != nil {
  310. return templ_7745c5c3_Err
  311. }
  312. var templ_7745c5c3_Var20 string
  313. templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.VolumeCount))
  314. if templ_7745c5c3_Err != nil {
  315. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 210, Col: 112}
  316. }
  317. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
  318. if templ_7745c5c3_Err != nil {
  319. return templ_7745c5c3_Err
  320. }
  321. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\" data-ec-volume-count=\"")
  322. if templ_7745c5c3_Err != nil {
  323. return templ_7745c5c3_Err
  324. }
  325. var templ_7745c5c3_Var21 string
  326. templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.EcVolumeCount))
  327. if templ_7745c5c3_Err != nil {
  328. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 211, Col: 117}
  329. }
  330. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
  331. if templ_7745c5c3_Err != nil {
  332. return templ_7745c5c3_Err
  333. }
  334. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\" data-file-count=\"")
  335. if templ_7745c5c3_Err != nil {
  336. return templ_7745c5c3_Err
  337. }
  338. var templ_7745c5c3_Var22 string
  339. templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.FileCount))
  340. if templ_7745c5c3_Err != nil {
  341. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 212, Col: 108}
  342. }
  343. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
  344. if templ_7745c5c3_Err != nil {
  345. return templ_7745c5c3_Err
  346. }
  347. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\" data-total-size=\"")
  348. if templ_7745c5c3_Err != nil {
  349. return templ_7745c5c3_Err
  350. }
  351. var templ_7745c5c3_Var23 string
  352. templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", collection.TotalSize))
  353. if templ_7745c5c3_Err != nil {
  354. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 213, Col: 108}
  355. }
  356. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
  357. if templ_7745c5c3_Err != nil {
  358. return templ_7745c5c3_Err
  359. }
  360. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\" data-disk-types=\"")
  361. if templ_7745c5c3_Err != nil {
  362. return templ_7745c5c3_Err
  363. }
  364. var templ_7745c5c3_Var24 string
  365. templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(formatDiskTypes(collection.DiskTypes))
  366. if templ_7745c5c3_Err != nil {
  367. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 214, Col: 106}
  368. }
  369. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
  370. if templ_7745c5c3_Err != nil {
  371. return templ_7745c5c3_Err
  372. }
  373. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\"><i class=\"fas fa-eye\"></i></button></td></tr>")
  374. if templ_7745c5c3_Err != nil {
  375. return templ_7745c5c3_Err
  376. }
  377. }
  378. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "</tbody></table></div>")
  379. if templ_7745c5c3_Err != nil {
  380. return templ_7745c5c3_Err
  381. }
  382. } else {
  383. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<div class=\"text-center py-5\"><i class=\"fas fa-layer-group fa-3x text-muted mb-3\"></i><h5 class=\"text-muted\">No Collections Found</h5><p class=\"text-muted\">No collections are currently configured in the cluster.</p></div>")
  384. if templ_7745c5c3_Err != nil {
  385. return templ_7745c5c3_Err
  386. }
  387. }
  388. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</div></div><!-- Last Updated --><div class=\"row\"><div class=\"col-12\"><small class=\"text-muted\"><i class=\"fas fa-clock me-1\"></i> Last updated: ")
  389. if templ_7745c5c3_Err != nil {
  390. return templ_7745c5c3_Err
  391. }
  392. var templ_7745c5c3_Var25 string
  393. templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastUpdated.Format("2006-01-02 15:04:05"))
  394. if templ_7745c5c3_Err != nil {
  395. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_collections.templ`, Line: 238, Col: 81}
  396. }
  397. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
  398. if templ_7745c5c3_Err != nil {
  399. return templ_7745c5c3_Err
  400. }
  401. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</small></div></div></div><!-- JavaScript for cluster collections functionality --><script>\n document.addEventListener('DOMContentLoaded', function() {\n // Handle collection action buttons\n document.addEventListener('click', function(e) {\n const button = e.target.closest('[data-action]');\n if (!button) return;\n \n const action = button.getAttribute('data-action');\n \n switch(action) {\n case 'view-details':\n const collectionData = {\n name: button.getAttribute('data-name'),\n datacenter: button.getAttribute('data-datacenter'),\n volumeCount: parseInt(button.getAttribute('data-volume-count')),\n ecVolumeCount: parseInt(button.getAttribute('data-ec-volume-count')),\n fileCount: parseInt(button.getAttribute('data-file-count')),\n totalSize: parseInt(button.getAttribute('data-total-size')),\n diskTypes: button.getAttribute('data-disk-types')\n };\n showCollectionDetails(collectionData);\n break;\n }\n });\n });\n \n function showCollectionDetails(collection) {\n const modalHtml = '<div class=\"modal fade\" id=\"collectionDetailsModal\" tabindex=\"-1\">' +\n '<div class=\"modal-dialog modal-lg\">' +\n '<div class=\"modal-content\">' +\n '<div class=\"modal-header\">' +\n '<h5 class=\"modal-title\"><i class=\"fas fa-layer-group me-2\"></i>Collection Details: ' + collection.name + '</h5>' +\n '<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"></button>' +\n '</div>' +\n '<div class=\"modal-body\">' +\n '<div class=\"row\">' +\n '<div class=\"col-md-6\">' +\n '<h6 class=\"text-primary\"><i class=\"fas fa-info-circle me-1\"></i>Basic Information</h6>' +\n '<table class=\"table table-sm\">' +\n '<tr><td><strong>Collection Name:</strong></td><td><code>' + collection.name + '</code></td></tr>' +\n '<tr><td><strong>Data Center:</strong></td><td>' +\n (collection.datacenter ? '<span class=\"badge bg-light text-dark\">' + collection.datacenter + '</span>' : '<span class=\"text-muted\">N/A</span>') +\n '</td></tr>' +\n '<tr><td><strong>Disk Types:</strong></td><td>' +\n (collection.diskTypes ? collection.diskTypes.split(', ').map(type => \n '<span class=\"badge bg-' + getDiskTypeBadgeColor(type) + ' me-1\">' + type + '</span>'\n ).join('') : '<span class=\"text-muted\">Unknown</span>') +\n '</td></tr>' +\n '</table>' +\n '</div>' +\n '<div class=\"col-md-6\">' +\n '<h6 class=\"text-primary\"><i class=\"fas fa-chart-bar me-1\"></i>Storage Statistics</h6>' +\n '<table class=\"table table-sm\">' +\n '<tr><td><strong>Regular Volumes:</strong></td><td>' +\n '<div class=\"d-flex align-items-center\">' +\n '<i class=\"fas fa-database me-2 text-muted\"></i>' +\n '<span>' + collection.volumeCount.toLocaleString() + '</span>' +\n '</div>' +\n '</td></tr>' +\n '<tr><td><strong>EC Volumes:</strong></td><td>' +\n '<div class=\"d-flex align-items-center\">' +\n '<i class=\"fas fa-th-large me-2 text-muted\"></i>' +\n '<span>' + collection.ecVolumeCount.toLocaleString() + '</span>' +\n '</div>' +\n '</td></tr>' +\n '<tr><td><strong>Total Files:</strong></td><td>' +\n '<div class=\"d-flex align-items-center\">' +\n '<i class=\"fas fa-file me-2 text-muted\"></i>' +\n '<span>' + collection.fileCount.toLocaleString() + '</span>' +\n '</div>' +\n '</td></tr>' +\n '<tr><td><strong>Total Size (Logical):</strong></td><td>' +\n '<div class=\"d-flex align-items-center\">' +\n '<i class=\"fas fa-hdd me-2 text-muted\"></i>' +\n '<span>' + formatBytes(collection.totalSize) + '</span>' +\n '</div>' +\n '</td></tr>' +\n '</table>' +\n '</div>' +\n '</div>' +\n '<div class=\"row mt-3\">' +\n '<div class=\"col-12\">' +\n '<h6 class=\"text-primary\"><i class=\"fas fa-link me-1\"></i>Quick Actions</h6>' +\n '<div class=\"d-grid gap-2 d-md-flex\">' +\n '<a href=\"/cluster/volumes?collection=' + encodeURIComponent(collection.name) + '\" class=\"btn btn-outline-primary\">' +\n '<i class=\"fas fa-database me-1\"></i>View Volumes' +\n '</a>' +\n '<a href=\"/cluster/ec-shards?collection=' + encodeURIComponent(collection.name) + '\" class=\"btn btn-outline-secondary\">' +\n '<i class=\"fas fa-th-large me-1\"></i>View EC Volumes' +\n '</a>' +\n '<a href=\"/files?collection=' + encodeURIComponent(collection.name) + '\" class=\"btn btn-outline-info\">' +\n '<i class=\"fas fa-folder me-1\"></i>Browse Files' +\n '</a>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '<div class=\"modal-footer\">' +\n '<button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Close</button>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>';\n \n // Remove existing modal if present\n const existingModal = document.getElementById('collectionDetailsModal');\n if (existingModal) {\n existingModal.remove();\n }\n \n // Add modal to body and show\n document.body.insertAdjacentHTML('beforeend', modalHtml);\n const modal = new bootstrap.Modal(document.getElementById('collectionDetailsModal'));\n modal.show();\n \n // Remove modal when hidden\n document.getElementById('collectionDetailsModal').addEventListener('hidden.bs.modal', function() {\n this.remove();\n });\n }\n \n function getDiskTypeBadgeColor(diskType) {\n switch(diskType.toLowerCase()) {\n case 'ssd':\n return 'primary';\n case 'hdd':\n case '':\n return 'secondary';\n default:\n return 'info';\n }\n }\n \n function formatBytes(bytes) {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n \n function exportCollections() {\n // Simple CSV export of collections list\n const rows = Array.from(document.querySelectorAll('#collectionsTable tbody tr')).map(row => {\n const cells = row.querySelectorAll('td');\n if (cells.length > 1) {\n return {\n name: cells[0].textContent.trim(),\n volumes: cells[1].textContent.trim(),\n files: cells[2].textContent.trim(),\n size: cells[3].textContent.trim(),\n diskTypes: cells[4].textContent.trim()\n };\n }\n return null;\n }).filter(row => row !== null);\n \n const csvContent = \"data:text/csv;charset=utf-8,\" + \n \"Collection Name,Volumes,Files,Size,Disk Types\\n\" +\n rows.map(r => '\"' + r.name + '\",\"' + r.volumes + '\",\"' + r.files + '\",\"' + r.size + '\",\"' + r.diskTypes + '\"').join(\"\\n\");\n \n const encodedUri = encodeURI(csvContent);\n const link = document.createElement(\"a\");\n link.setAttribute(\"href\", encodedUri);\n link.setAttribute(\"download\", \"collections.csv\");\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n </script>")
  402. if templ_7745c5c3_Err != nil {
  403. return templ_7745c5c3_Err
  404. }
  405. return nil
  406. })
  407. }
  408. func getDiskTypeColor(diskType string) string {
  409. switch diskType {
  410. case "ssd":
  411. return "primary"
  412. case "hdd", "":
  413. return "secondary"
  414. default:
  415. return "info"
  416. }
  417. }
  418. func formatDiskTypes(diskTypes []string) string {
  419. if len(diskTypes) == 0 {
  420. return "Unknown"
  421. }
  422. if len(diskTypes) == 1 {
  423. return diskTypes[0]
  424. }
  425. // For multiple disk types, join with comma
  426. result := ""
  427. for i, diskType := range diskTypes {
  428. if i > 0 {
  429. result += ", "
  430. }
  431. result += diskType
  432. }
  433. return result
  434. }
  435. var _ = templruntime.GeneratedTemplate