task_detail_templ.go 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628
  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/maintenance"
  10. "github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding"
  11. "sort"
  12. )
  13. // sortedKeys returns the sorted keys for a string map
  14. func sortedKeys(m map[string]string) []string {
  15. keys := make([]string, 0, len(m))
  16. for k := range m {
  17. keys = append(keys, k)
  18. }
  19. sort.Strings(keys)
  20. return keys
  21. }
  22. func TaskDetail(data *maintenance.TaskDetailData) templ.Component {
  23. return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
  24. templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
  25. if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
  26. return templ_7745c5c3_CtxErr
  27. }
  28. templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
  29. if !templ_7745c5c3_IsBuffer {
  30. defer func() {
  31. templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
  32. if templ_7745c5c3_Err == nil {
  33. templ_7745c5c3_Err = templ_7745c5c3_BufErr
  34. }
  35. }()
  36. }
  37. ctx = templ.InitializeContext(ctx)
  38. templ_7745c5c3_Var1 := templ.GetChildren(ctx)
  39. if templ_7745c5c3_Var1 == nil {
  40. templ_7745c5c3_Var1 = templ.NopComponent
  41. }
  42. ctx = templ.ClearChildren(ctx)
  43. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"container-fluid\"><!-- Header --><div class=\"row mb-4\"><div class=\"col-12\"><div class=\"d-flex justify-content-between align-items-center\"><div><nav aria-label=\"breadcrumb\"><ol class=\"breadcrumb mb-1\"><li class=\"breadcrumb-item\"><a href=\"/maintenance\">Maintenance</a></li><li class=\"breadcrumb-item active\" aria-current=\"page\">Task Detail</li></ol></nav><h2 class=\"mb-0\"><i class=\"fas fa-tasks me-2\"></i> Task Detail: ")
  44. if templ_7745c5c3_Err != nil {
  45. return templ_7745c5c3_Err
  46. }
  47. var templ_7745c5c3_Var2 string
  48. templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ID)
  49. if templ_7745c5c3_Err != nil {
  50. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 35, Col: 54}
  51. }
  52. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
  53. if templ_7745c5c3_Err != nil {
  54. return templ_7745c5c3_Err
  55. }
  56. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</h2></div><div class=\"btn-group\"><button type=\"button\" class=\"btn btn-secondary\" onclick=\"history.back()\"><i class=\"fas fa-arrow-left me-1\"></i> Back</button> <button type=\"button\" class=\"btn btn-secondary\" onclick=\"refreshPage()\"><i class=\"fas fa-sync-alt me-1\"></i> Refresh</button></div></div></div></div><!-- Task Overview Card --><div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-info-circle me-2\"></i> Task Overview</h5></div><div class=\"card-body\"><div class=\"row\"><div class=\"col-md-6\"><dl class=\"row\"><dt class=\"col-sm-4\">Task ID:</dt><dd class=\"col-sm-8\"><code>")
  57. if templ_7745c5c3_Err != nil {
  58. return templ_7745c5c3_Err
  59. }
  60. var templ_7745c5c3_Var3 string
  61. templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ID)
  62. if templ_7745c5c3_Err != nil {
  63. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 67, Col: 76}
  64. }
  65. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
  66. if templ_7745c5c3_Err != nil {
  67. return templ_7745c5c3_Err
  68. }
  69. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</code></dd><dt class=\"col-sm-4\">Type:</dt><dd class=\"col-sm-8\"><span class=\"badge bg-info\">")
  70. if templ_7745c5c3_Err != nil {
  71. return templ_7745c5c3_Err
  72. }
  73. var templ_7745c5c3_Var4 string
  74. templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(string(data.Task.Type))
  75. if templ_7745c5c3_Err != nil {
  76. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 71, Col: 91}
  77. }
  78. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
  79. if templ_7745c5c3_Err != nil {
  80. return templ_7745c5c3_Err
  81. }
  82. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</span></dd><dt class=\"col-sm-4\">Status:</dt><dd class=\"col-sm-8\">")
  83. if templ_7745c5c3_Err != nil {
  84. return templ_7745c5c3_Err
  85. }
  86. if data.Task.Status == maintenance.TaskStatusPending {
  87. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<span class=\"badge bg-secondary\">Pending</span>")
  88. if templ_7745c5c3_Err != nil {
  89. return templ_7745c5c3_Err
  90. }
  91. } else if data.Task.Status == maintenance.TaskStatusAssigned {
  92. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<span class=\"badge bg-info\">Assigned</span>")
  93. if templ_7745c5c3_Err != nil {
  94. return templ_7745c5c3_Err
  95. }
  96. } else if data.Task.Status == maintenance.TaskStatusInProgress {
  97. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<span class=\"badge bg-warning\">In Progress</span>")
  98. if templ_7745c5c3_Err != nil {
  99. return templ_7745c5c3_Err
  100. }
  101. } else if data.Task.Status == maintenance.TaskStatusCompleted {
  102. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<span class=\"badge bg-success\">Completed</span>")
  103. if templ_7745c5c3_Err != nil {
  104. return templ_7745c5c3_Err
  105. }
  106. } else if data.Task.Status == maintenance.TaskStatusFailed {
  107. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<span class=\"badge bg-danger\">Failed</span>")
  108. if templ_7745c5c3_Err != nil {
  109. return templ_7745c5c3_Err
  110. }
  111. } else if data.Task.Status == maintenance.TaskStatusCancelled {
  112. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<span class=\"badge bg-dark\">Cancelled</span>")
  113. if templ_7745c5c3_Err != nil {
  114. return templ_7745c5c3_Err
  115. }
  116. }
  117. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</dd><dt class=\"col-sm-4\">Priority:</dt><dd class=\"col-sm-8\">")
  118. if templ_7745c5c3_Err != nil {
  119. return templ_7745c5c3_Err
  120. }
  121. if data.Task.Priority == maintenance.PriorityHigh {
  122. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<span class=\"badge bg-danger\">High</span>")
  123. if templ_7745c5c3_Err != nil {
  124. return templ_7745c5c3_Err
  125. }
  126. } else if data.Task.Priority == maintenance.PriorityCritical {
  127. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<span class=\"badge bg-danger\">Critical</span>")
  128. if templ_7745c5c3_Err != nil {
  129. return templ_7745c5c3_Err
  130. }
  131. } else if data.Task.Priority == maintenance.PriorityNormal {
  132. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<span class=\"badge bg-warning\">Normal</span>")
  133. if templ_7745c5c3_Err != nil {
  134. return templ_7745c5c3_Err
  135. }
  136. } else {
  137. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<span class=\"badge bg-secondary\">Low</span>")
  138. if templ_7745c5c3_Err != nil {
  139. return templ_7745c5c3_Err
  140. }
  141. }
  142. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</dd>")
  143. if templ_7745c5c3_Err != nil {
  144. return templ_7745c5c3_Err
  145. }
  146. if data.Task.Reason != "" {
  147. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<dt class=\"col-sm-4\">Reason:</dt><dd class=\"col-sm-8\"><span class=\"text-muted\">")
  148. if templ_7745c5c3_Err != nil {
  149. return templ_7745c5c3_Err
  150. }
  151. var templ_7745c5c3_Var5 string
  152. templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.Reason)
  153. if templ_7745c5c3_Err != nil {
  154. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 107, Col: 86}
  155. }
  156. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
  157. if templ_7745c5c3_Err != nil {
  158. return templ_7745c5c3_Err
  159. }
  160. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</span></dd>")
  161. if templ_7745c5c3_Err != nil {
  162. return templ_7745c5c3_Err
  163. }
  164. }
  165. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</dl></div><div class=\"col-md-6\"><!-- Task Timeline --><div class=\"mb-3\"><h6 class=\"text-primary mb-3\"><i class=\"fas fa-clock me-1\"></i>Task Timeline</h6><div class=\"timeline-container\"><div class=\"timeline-progress\"><div class=\"timeline-step\" data-step=\"created\"><div class=\"timeline-circle completed\"><i class=\"fas fa-plus\"></i></div><div class=\"timeline-connector completed\"></div><div class=\"timeline-label\"><strong>Created</strong> <small class=\"d-block text-muted\">")
  166. if templ_7745c5c3_Err != nil {
  167. return templ_7745c5c3_Err
  168. }
  169. var templ_7745c5c3_Var6 string
  170. templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.CreatedAt.Format("01-02 15:04:05"))
  171. if templ_7745c5c3_Err != nil {
  172. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 127, Col: 131}
  173. }
  174. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
  175. if templ_7745c5c3_Err != nil {
  176. return templ_7745c5c3_Err
  177. }
  178. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</small></div></div><div class=\"timeline-step\" data-step=\"scheduled\"><div class=\"timeline-circle completed\"><i class=\"fas fa-calendar\"></i></div>")
  179. if templ_7745c5c3_Err != nil {
  180. return templ_7745c5c3_Err
  181. }
  182. if data.Task.StartedAt != nil {
  183. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<div class=\"timeline-connector completed\"></div>")
  184. if templ_7745c5c3_Err != nil {
  185. return templ_7745c5c3_Err
  186. }
  187. } else {
  188. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<div class=\"timeline-connector\"></div>")
  189. if templ_7745c5c3_Err != nil {
  190. return templ_7745c5c3_Err
  191. }
  192. }
  193. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<div class=\"timeline-label\"><strong>Scheduled</strong> <small class=\"d-block text-muted\">")
  194. if templ_7745c5c3_Err != nil {
  195. return templ_7745c5c3_Err
  196. }
  197. var templ_7745c5c3_Var7 string
  198. templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ScheduledAt.Format("01-02 15:04:05"))
  199. if templ_7745c5c3_Err != nil {
  200. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 142, Col: 133}
  201. }
  202. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
  203. if templ_7745c5c3_Err != nil {
  204. return templ_7745c5c3_Err
  205. }
  206. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</small></div></div><div class=\"timeline-step\" data-step=\"started\">")
  207. if templ_7745c5c3_Err != nil {
  208. return templ_7745c5c3_Err
  209. }
  210. if data.Task.StartedAt != nil {
  211. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<div class=\"timeline-circle completed\"><i class=\"fas fa-play\"></i></div>")
  212. if templ_7745c5c3_Err != nil {
  213. return templ_7745c5c3_Err
  214. }
  215. } else {
  216. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<div class=\"timeline-circle pending\"><i class=\"fas fa-clock\"></i></div>")
  217. if templ_7745c5c3_Err != nil {
  218. return templ_7745c5c3_Err
  219. }
  220. }
  221. if data.Task.CompletedAt != nil {
  222. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<div class=\"timeline-connector completed\"></div>")
  223. if templ_7745c5c3_Err != nil {
  224. return templ_7745c5c3_Err
  225. }
  226. } else {
  227. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<div class=\"timeline-connector\"></div>")
  228. if templ_7745c5c3_Err != nil {
  229. return templ_7745c5c3_Err
  230. }
  231. }
  232. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<div class=\"timeline-label\"><strong>Started</strong> <small class=\"d-block text-muted\">")
  233. if templ_7745c5c3_Err != nil {
  234. return templ_7745c5c3_Err
  235. }
  236. if data.Task.StartedAt != nil {
  237. var templ_7745c5c3_Var8 string
  238. templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.StartedAt.Format("01-02 15:04:05"))
  239. if templ_7745c5c3_Err != nil {
  240. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 165, Col: 105}
  241. }
  242. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
  243. if templ_7745c5c3_Err != nil {
  244. return templ_7745c5c3_Err
  245. }
  246. } else {
  247. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "—")
  248. if templ_7745c5c3_Err != nil {
  249. return templ_7745c5c3_Err
  250. }
  251. }
  252. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</small></div></div><div class=\"timeline-step\" data-step=\"completed\">")
  253. if templ_7745c5c3_Err != nil {
  254. return templ_7745c5c3_Err
  255. }
  256. if data.Task.CompletedAt != nil {
  257. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<div class=\"timeline-circle completed\">")
  258. if templ_7745c5c3_Err != nil {
  259. return templ_7745c5c3_Err
  260. }
  261. if data.Task.Status == maintenance.TaskStatusCompleted {
  262. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<i class=\"fas fa-check\"></i>")
  263. if templ_7745c5c3_Err != nil {
  264. return templ_7745c5c3_Err
  265. }
  266. } else if data.Task.Status == maintenance.TaskStatusFailed {
  267. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<i class=\"fas fa-times\"></i>")
  268. if templ_7745c5c3_Err != nil {
  269. return templ_7745c5c3_Err
  270. }
  271. } else {
  272. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<i class=\"fas fa-stop\"></i>")
  273. if templ_7745c5c3_Err != nil {
  274. return templ_7745c5c3_Err
  275. }
  276. }
  277. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</div>")
  278. if templ_7745c5c3_Err != nil {
  279. return templ_7745c5c3_Err
  280. }
  281. } else {
  282. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div class=\"timeline-circle pending\"><i class=\"fas fa-hourglass-half\"></i></div>")
  283. if templ_7745c5c3_Err != nil {
  284. return templ_7745c5c3_Err
  285. }
  286. }
  287. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div class=\"timeline-label\"><strong>")
  288. if templ_7745c5c3_Err != nil {
  289. return templ_7745c5c3_Err
  290. }
  291. if data.Task.Status == maintenance.TaskStatusCompleted {
  292. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "Completed")
  293. if templ_7745c5c3_Err != nil {
  294. return templ_7745c5c3_Err
  295. }
  296. } else if data.Task.Status == maintenance.TaskStatusFailed {
  297. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "Failed")
  298. if templ_7745c5c3_Err != nil {
  299. return templ_7745c5c3_Err
  300. }
  301. } else if data.Task.Status == maintenance.TaskStatusCancelled {
  302. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "Cancelled")
  303. if templ_7745c5c3_Err != nil {
  304. return templ_7745c5c3_Err
  305. }
  306. } else {
  307. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "Pending")
  308. if templ_7745c5c3_Err != nil {
  309. return templ_7745c5c3_Err
  310. }
  311. }
  312. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</strong> <small class=\"d-block text-muted\">")
  313. if templ_7745c5c3_Err != nil {
  314. return templ_7745c5c3_Err
  315. }
  316. if data.Task.CompletedAt != nil {
  317. var templ_7745c5c3_Var9 string
  318. templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.CompletedAt.Format("01-02 15:04:05"))
  319. if templ_7745c5c3_Err != nil {
  320. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 203, Col: 107}
  321. }
  322. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
  323. if templ_7745c5c3_Err != nil {
  324. return templ_7745c5c3_Err
  325. }
  326. } else {
  327. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "—")
  328. if templ_7745c5c3_Err != nil {
  329. return templ_7745c5c3_Err
  330. }
  331. }
  332. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "</small></div></div></div></div></div><!-- Additional Info -->")
  333. if templ_7745c5c3_Err != nil {
  334. return templ_7745c5c3_Err
  335. }
  336. if data.Task.WorkerID != "" {
  337. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<dl class=\"row\"><dt class=\"col-sm-4\">Worker:</dt><dd class=\"col-sm-8\"><code>")
  338. if templ_7745c5c3_Err != nil {
  339. return templ_7745c5c3_Err
  340. }
  341. var templ_7745c5c3_Var10 string
  342. templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.WorkerID)
  343. if templ_7745c5c3_Err != nil {
  344. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 218, Col: 86}
  345. }
  346. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
  347. if templ_7745c5c3_Err != nil {
  348. return templ_7745c5c3_Err
  349. }
  350. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</code></dd></dl>")
  351. if templ_7745c5c3_Err != nil {
  352. return templ_7745c5c3_Err
  353. }
  354. }
  355. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "<dl class=\"row\">")
  356. if templ_7745c5c3_Err != nil {
  357. return templ_7745c5c3_Err
  358. }
  359. if data.Task.TypedParams != nil && data.Task.TypedParams.VolumeSize > 0 {
  360. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<dt class=\"col-sm-4\">Volume Size:</dt><dd class=\"col-sm-8\"><span class=\"badge bg-primary\">")
  361. if templ_7745c5c3_Err != nil {
  362. return templ_7745c5c3_Err
  363. }
  364. var templ_7745c5c3_Var11 string
  365. templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(int64(data.Task.TypedParams.VolumeSize)))
  366. if templ_7745c5c3_Err != nil {
  367. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 226, Col: 128}
  368. }
  369. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
  370. if templ_7745c5c3_Err != nil {
  371. return templ_7745c5c3_Err
  372. }
  373. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</span></dd>")
  374. if templ_7745c5c3_Err != nil {
  375. return templ_7745c5c3_Err
  376. }
  377. }
  378. if data.Task.TypedParams != nil && data.Task.TypedParams.Collection != "" {
  379. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<dt class=\"col-sm-4\">Collection:</dt><dd class=\"col-sm-8\"><span class=\"badge bg-info\"><i class=\"fas fa-folder me-1\"></i>")
  380. if templ_7745c5c3_Err != nil {
  381. return templ_7745c5c3_Err
  382. }
  383. var templ_7745c5c3_Var12 string
  384. templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.TypedParams.Collection)
  385. if templ_7745c5c3_Err != nil {
  386. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 233, Col: 139}
  387. }
  388. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
  389. if templ_7745c5c3_Err != nil {
  390. return templ_7745c5c3_Err
  391. }
  392. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "</span></dd>")
  393. if templ_7745c5c3_Err != nil {
  394. return templ_7745c5c3_Err
  395. }
  396. }
  397. if data.Task.TypedParams != nil && data.Task.TypedParams.DataCenter != "" {
  398. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "<dt class=\"col-sm-4\">Data Center:</dt><dd class=\"col-sm-8\"><span class=\"badge bg-secondary\"><i class=\"fas fa-building me-1\"></i>")
  399. if templ_7745c5c3_Err != nil {
  400. return templ_7745c5c3_Err
  401. }
  402. var templ_7745c5c3_Var13 string
  403. templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.TypedParams.DataCenter)
  404. if templ_7745c5c3_Err != nil {
  405. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 240, Col: 146}
  406. }
  407. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
  408. if templ_7745c5c3_Err != nil {
  409. return templ_7745c5c3_Err
  410. }
  411. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</span></dd>")
  412. if templ_7745c5c3_Err != nil {
  413. return templ_7745c5c3_Err
  414. }
  415. }
  416. if data.Task.Progress > 0 {
  417. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "<dt class=\"col-sm-4\">Progress:</dt><dd class=\"col-sm-8\"><div class=\"progress\" style=\"height: 20px;\"><div class=\"progress-bar\" role=\"progressbar\" style=\"")
  418. if templ_7745c5c3_Err != nil {
  419. return templ_7745c5c3_Err
  420. }
  421. var templ_7745c5c3_Var14 string
  422. templ_7745c5c3_Var14, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(fmt.Sprintf("width: %.1f%%", data.Task.Progress))
  423. if templ_7745c5c3_Err != nil {
  424. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 249, Col: 108}
  425. }
  426. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
  427. if templ_7745c5c3_Err != nil {
  428. return templ_7745c5c3_Err
  429. }
  430. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "\" aria-valuenow=\"")
  431. if templ_7745c5c3_Err != nil {
  432. return templ_7745c5c3_Err
  433. }
  434. var templ_7745c5c3_Var15 string
  435. templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", data.Task.Progress))
  436. if templ_7745c5c3_Err != nil {
  437. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 250, Col: 107}
  438. }
  439. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
  440. if templ_7745c5c3_Err != nil {
  441. return templ_7745c5c3_Err
  442. }
  443. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "\" aria-valuemin=\"0\" aria-valuemax=\"100\">")
  444. if templ_7745c5c3_Err != nil {
  445. return templ_7745c5c3_Err
  446. }
  447. var templ_7745c5c3_Var16 string
  448. templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f%%", data.Task.Progress))
  449. if templ_7745c5c3_Err != nil {
  450. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 252, Col: 94}
  451. }
  452. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
  453. if templ_7745c5c3_Err != nil {
  454. return templ_7745c5c3_Err
  455. }
  456. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</div></div></dd>")
  457. if templ_7745c5c3_Err != nil {
  458. return templ_7745c5c3_Err
  459. }
  460. }
  461. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</dl></div></div>")
  462. if templ_7745c5c3_Err != nil {
  463. return templ_7745c5c3_Err
  464. }
  465. if data.Task.DetailedReason != "" {
  466. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<div class=\"row mt-3\"><div class=\"col-12\"><h6>Detailed Reason:</h6><p class=\"text-muted\">")
  467. if templ_7745c5c3_Err != nil {
  468. return templ_7745c5c3_Err
  469. }
  470. var templ_7745c5c3_Var17 string
  471. templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.DetailedReason)
  472. if templ_7745c5c3_Err != nil {
  473. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 267, Col: 83}
  474. }
  475. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
  476. if templ_7745c5c3_Err != nil {
  477. return templ_7745c5c3_Err
  478. }
  479. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</p></div></div>")
  480. if templ_7745c5c3_Err != nil {
  481. return templ_7745c5c3_Err
  482. }
  483. }
  484. if data.Task.Error != "" {
  485. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "<div class=\"row mt-3\"><div class=\"col-12\"><h6>Error:</h6><div class=\"alert alert-danger\"><code>")
  486. if templ_7745c5c3_Err != nil {
  487. return templ_7745c5c3_Err
  488. }
  489. var templ_7745c5c3_Var18 string
  490. templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.Error)
  491. if templ_7745c5c3_Err != nil {
  492. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 277, Col: 62}
  493. }
  494. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
  495. if templ_7745c5c3_Err != nil {
  496. return templ_7745c5c3_Err
  497. }
  498. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</code></div></div></div>")
  499. if templ_7745c5c3_Err != nil {
  500. return templ_7745c5c3_Err
  501. }
  502. }
  503. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "</div></div></div></div><!-- Task Configuration Card -->")
  504. if templ_7745c5c3_Err != nil {
  505. return templ_7745c5c3_Err
  506. }
  507. if data.Task.TypedParams != nil {
  508. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "<div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-cog me-2\"></i> Task Configuration</h5></div><div class=\"card-body\"><!-- Source Servers (Unified) -->")
  509. if templ_7745c5c3_Err != nil {
  510. return templ_7745c5c3_Err
  511. }
  512. if len(data.Task.TypedParams.Sources) > 0 {
  513. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<div class=\"mb-4\"><h6 class=\"text-info d-flex align-items-center\"><i class=\"fas fa-server me-2\"></i> Source Servers <span class=\"badge bg-info ms-2\">")
  514. if templ_7745c5c3_Err != nil {
  515. return templ_7745c5c3_Err
  516. }
  517. var templ_7745c5c3_Var19 string
  518. templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.Task.TypedParams.Sources)))
  519. if templ_7745c5c3_Err != nil {
  520. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 305, Col: 127}
  521. }
  522. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
  523. if templ_7745c5c3_Err != nil {
  524. return templ_7745c5c3_Err
  525. }
  526. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</span></h6><div class=\"bg-light p-3 rounded\"><div class=\"d-flex flex-column gap-2\">")
  527. if templ_7745c5c3_Err != nil {
  528. return templ_7745c5c3_Err
  529. }
  530. for i, source := range data.Task.TypedParams.Sources {
  531. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<div class=\"d-grid\" style=\"grid-template-columns: auto 1fr auto auto auto auto; gap: 0.5rem; align-items: center;\"><span class=\"badge bg-primary\">")
  532. if templ_7745c5c3_Err != nil {
  533. return templ_7745c5c3_Err
  534. }
  535. var templ_7745c5c3_Var20 string
  536. templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("#%d", i+1))
  537. if templ_7745c5c3_Err != nil {
  538. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 311, Col: 91}
  539. }
  540. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
  541. if templ_7745c5c3_Err != nil {
  542. return templ_7745c5c3_Err
  543. }
  544. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "</span> <code>")
  545. if templ_7745c5c3_Err != nil {
  546. return templ_7745c5c3_Err
  547. }
  548. var templ_7745c5c3_Var21 string
  549. templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(source.Node)
  550. if templ_7745c5c3_Err != nil {
  551. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 312, Col: 54}
  552. }
  553. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
  554. if templ_7745c5c3_Err != nil {
  555. return templ_7745c5c3_Err
  556. }
  557. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</code><div>")
  558. if templ_7745c5c3_Err != nil {
  559. return templ_7745c5c3_Err
  560. }
  561. if source.DataCenter != "" {
  562. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<small class=\"text-muted\"><i class=\"fas fa-building me-1\"></i>")
  563. if templ_7745c5c3_Err != nil {
  564. return templ_7745c5c3_Err
  565. }
  566. var templ_7745c5c3_Var22 string
  567. templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(source.DataCenter)
  568. if templ_7745c5c3_Err != nil {
  569. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 316, Col: 102}
  570. }
  571. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
  572. if templ_7745c5c3_Err != nil {
  573. return templ_7745c5c3_Err
  574. }
  575. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</small>")
  576. if templ_7745c5c3_Err != nil {
  577. return templ_7745c5c3_Err
  578. }
  579. }
  580. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</div><div>")
  581. if templ_7745c5c3_Err != nil {
  582. return templ_7745c5c3_Err
  583. }
  584. if source.Rack != "" {
  585. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "<small class=\"text-muted\"><i class=\"fas fa-server me-1\"></i>")
  586. if templ_7745c5c3_Err != nil {
  587. return templ_7745c5c3_Err
  588. }
  589. var templ_7745c5c3_Var23 string
  590. templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(source.Rack)
  591. if templ_7745c5c3_Err != nil {
  592. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 323, Col: 94}
  593. }
  594. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
  595. if templ_7745c5c3_Err != nil {
  596. return templ_7745c5c3_Err
  597. }
  598. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</small>")
  599. if templ_7745c5c3_Err != nil {
  600. return templ_7745c5c3_Err
  601. }
  602. }
  603. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</div><div>")
  604. if templ_7745c5c3_Err != nil {
  605. return templ_7745c5c3_Err
  606. }
  607. if source.VolumeId > 0 {
  608. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<small class=\"text-muted\"><i class=\"fas fa-hdd me-1\"></i>Vol:")
  609. if templ_7745c5c3_Err != nil {
  610. return templ_7745c5c3_Err
  611. }
  612. var templ_7745c5c3_Var24 string
  613. templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", source.VolumeId))
  614. if templ_7745c5c3_Err != nil {
  615. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 330, Col: 118}
  616. }
  617. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
  618. if templ_7745c5c3_Err != nil {
  619. return templ_7745c5c3_Err
  620. }
  621. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</small>")
  622. if templ_7745c5c3_Err != nil {
  623. return templ_7745c5c3_Err
  624. }
  625. }
  626. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</div><div>")
  627. if templ_7745c5c3_Err != nil {
  628. return templ_7745c5c3_Err
  629. }
  630. if len(source.ShardIds) > 0 {
  631. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<small class=\"text-muted\"><i class=\"fas fa-puzzle-piece me-1\"></i>Shards: ")
  632. if templ_7745c5c3_Err != nil {
  633. return templ_7745c5c3_Err
  634. }
  635. for j, shardId := range source.ShardIds {
  636. if j > 0 {
  637. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<span>, </span>")
  638. if templ_7745c5c3_Err != nil {
  639. return templ_7745c5c3_Err
  640. }
  641. }
  642. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, " ")
  643. if templ_7745c5c3_Err != nil {
  644. return templ_7745c5c3_Err
  645. }
  646. if shardId < erasure_coding.DataShardsCount {
  647. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<span class=\"badge badge-sm bg-primary ms-1\" style=\"font-size: 0.65rem;\" title=\"")
  648. if templ_7745c5c3_Err != nil {
  649. return templ_7745c5c3_Err
  650. }
  651. var templ_7745c5c3_Var25 string
  652. templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("Data shard %d", shardId))
  653. if templ_7745c5c3_Err != nil {
  654. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 343, Col: 173}
  655. }
  656. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
  657. if templ_7745c5c3_Err != nil {
  658. return templ_7745c5c3_Err
  659. }
  660. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\">")
  661. if templ_7745c5c3_Err != nil {
  662. return templ_7745c5c3_Err
  663. }
  664. var templ_7745c5c3_Var26 string
  665. templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", shardId))
  666. if templ_7745c5c3_Err != nil {
  667. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 343, Col: 202}
  668. }
  669. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
  670. if templ_7745c5c3_Err != nil {
  671. return templ_7745c5c3_Err
  672. }
  673. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "</span>")
  674. if templ_7745c5c3_Err != nil {
  675. return templ_7745c5c3_Err
  676. }
  677. } else {
  678. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<span class=\"badge badge-sm bg-warning text-dark ms-1\" style=\"font-size: 0.65rem;\" title=\"")
  679. if templ_7745c5c3_Err != nil {
  680. return templ_7745c5c3_Err
  681. }
  682. var templ_7745c5c3_Var27 string
  683. templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("Parity shard %d", shardId))
  684. if templ_7745c5c3_Err != nil {
  685. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 345, Col: 185}
  686. }
  687. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
  688. if templ_7745c5c3_Err != nil {
  689. return templ_7745c5c3_Err
  690. }
  691. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">")
  692. if templ_7745c5c3_Err != nil {
  693. return templ_7745c5c3_Err
  694. }
  695. var templ_7745c5c3_Var28 string
  696. templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("P%d", shardId-erasure_coding.DataShardsCount))
  697. if templ_7745c5c3_Err != nil {
  698. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 345, Col: 246}
  699. }
  700. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
  701. if templ_7745c5c3_Err != nil {
  702. return templ_7745c5c3_Err
  703. }
  704. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</span>")
  705. if templ_7745c5c3_Err != nil {
  706. return templ_7745c5c3_Err
  707. }
  708. }
  709. }
  710. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</small>")
  711. if templ_7745c5c3_Err != nil {
  712. return templ_7745c5c3_Err
  713. }
  714. }
  715. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "</div></div>")
  716. if templ_7745c5c3_Err != nil {
  717. return templ_7745c5c3_Err
  718. }
  719. }
  720. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</div></div></div>")
  721. if templ_7745c5c3_Err != nil {
  722. return templ_7745c5c3_Err
  723. }
  724. }
  725. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<!-- Task Flow Indicator -->")
  726. if templ_7745c5c3_Err != nil {
  727. return templ_7745c5c3_Err
  728. }
  729. if len(data.Task.TypedParams.Sources) > 0 || len(data.Task.TypedParams.Targets) > 0 {
  730. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<div class=\"text-center mb-3\"><i class=\"fas fa-arrow-down text-primary\" style=\"font-size: 1.5rem;\"></i><br><small class=\"text-muted\">Task: ")
  731. if templ_7745c5c3_Err != nil {
  732. return templ_7745c5c3_Err
  733. }
  734. var templ_7745c5c3_Var29 string
  735. templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(string(data.Task.Type))
  736. if templ_7745c5c3_Err != nil {
  737. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 363, Col: 91}
  738. }
  739. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
  740. if templ_7745c5c3_Err != nil {
  741. return templ_7745c5c3_Err
  742. }
  743. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "</small></div>")
  744. if templ_7745c5c3_Err != nil {
  745. return templ_7745c5c3_Err
  746. }
  747. }
  748. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "<!-- Target/Destination (Generic) -->")
  749. if templ_7745c5c3_Err != nil {
  750. return templ_7745c5c3_Err
  751. }
  752. if len(data.Task.TypedParams.Targets) > 0 {
  753. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<div class=\"mb-4\"><h6 class=\"text-success d-flex align-items-center\"><i class=\"fas fa-bullseye me-2\"></i> Target Servers <span class=\"badge bg-success ms-2\">")
  754. if templ_7745c5c3_Err != nil {
  755. return templ_7745c5c3_Err
  756. }
  757. var templ_7745c5c3_Var30 string
  758. templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.Task.TypedParams.Targets)))
  759. if templ_7745c5c3_Err != nil {
  760. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 373, Col: 130}
  761. }
  762. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
  763. if templ_7745c5c3_Err != nil {
  764. return templ_7745c5c3_Err
  765. }
  766. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</span></h6><div class=\"bg-light p-3 rounded\"><div class=\"d-flex flex-column gap-2\">")
  767. if templ_7745c5c3_Err != nil {
  768. return templ_7745c5c3_Err
  769. }
  770. for i, target := range data.Task.TypedParams.Targets {
  771. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<div class=\"d-grid\" style=\"grid-template-columns: auto 1fr auto auto auto auto; gap: 0.5rem; align-items: center;\"><span class=\"badge bg-success\">")
  772. if templ_7745c5c3_Err != nil {
  773. return templ_7745c5c3_Err
  774. }
  775. var templ_7745c5c3_Var31 string
  776. templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("#%d", i+1))
  777. if templ_7745c5c3_Err != nil {
  778. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 379, Col: 91}
  779. }
  780. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
  781. if templ_7745c5c3_Err != nil {
  782. return templ_7745c5c3_Err
  783. }
  784. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</span> <code>")
  785. if templ_7745c5c3_Err != nil {
  786. return templ_7745c5c3_Err
  787. }
  788. var templ_7745c5c3_Var32 string
  789. templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(target.Node)
  790. if templ_7745c5c3_Err != nil {
  791. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 380, Col: 54}
  792. }
  793. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
  794. if templ_7745c5c3_Err != nil {
  795. return templ_7745c5c3_Err
  796. }
  797. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</code><div>")
  798. if templ_7745c5c3_Err != nil {
  799. return templ_7745c5c3_Err
  800. }
  801. if target.DataCenter != "" {
  802. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "<small class=\"text-muted\"><i class=\"fas fa-building me-1\"></i>")
  803. if templ_7745c5c3_Err != nil {
  804. return templ_7745c5c3_Err
  805. }
  806. var templ_7745c5c3_Var33 string
  807. templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(target.DataCenter)
  808. if templ_7745c5c3_Err != nil {
  809. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 384, Col: 102}
  810. }
  811. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
  812. if templ_7745c5c3_Err != nil {
  813. return templ_7745c5c3_Err
  814. }
  815. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "</small>")
  816. if templ_7745c5c3_Err != nil {
  817. return templ_7745c5c3_Err
  818. }
  819. }
  820. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "</div><div>")
  821. if templ_7745c5c3_Err != nil {
  822. return templ_7745c5c3_Err
  823. }
  824. if target.Rack != "" {
  825. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<small class=\"text-muted\"><i class=\"fas fa-server me-1\"></i>")
  826. if templ_7745c5c3_Err != nil {
  827. return templ_7745c5c3_Err
  828. }
  829. var templ_7745c5c3_Var34 string
  830. templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(target.Rack)
  831. if templ_7745c5c3_Err != nil {
  832. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 391, Col: 94}
  833. }
  834. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
  835. if templ_7745c5c3_Err != nil {
  836. return templ_7745c5c3_Err
  837. }
  838. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "</small>")
  839. if templ_7745c5c3_Err != nil {
  840. return templ_7745c5c3_Err
  841. }
  842. }
  843. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "</div><div>")
  844. if templ_7745c5c3_Err != nil {
  845. return templ_7745c5c3_Err
  846. }
  847. if target.VolumeId > 0 {
  848. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<small class=\"text-muted\"><i class=\"fas fa-hdd me-1\"></i>Vol:")
  849. if templ_7745c5c3_Err != nil {
  850. return templ_7745c5c3_Err
  851. }
  852. var templ_7745c5c3_Var35 string
  853. templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", target.VolumeId))
  854. if templ_7745c5c3_Err != nil {
  855. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 398, Col: 118}
  856. }
  857. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
  858. if templ_7745c5c3_Err != nil {
  859. return templ_7745c5c3_Err
  860. }
  861. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</small>")
  862. if templ_7745c5c3_Err != nil {
  863. return templ_7745c5c3_Err
  864. }
  865. }
  866. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</div><div>")
  867. if templ_7745c5c3_Err != nil {
  868. return templ_7745c5c3_Err
  869. }
  870. if len(target.ShardIds) > 0 {
  871. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "<small class=\"text-muted\"><i class=\"fas fa-puzzle-piece me-1\"></i>Shards: ")
  872. if templ_7745c5c3_Err != nil {
  873. return templ_7745c5c3_Err
  874. }
  875. for j, shardId := range target.ShardIds {
  876. if j > 0 {
  877. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "<span>, </span>")
  878. if templ_7745c5c3_Err != nil {
  879. return templ_7745c5c3_Err
  880. }
  881. }
  882. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, " ")
  883. if templ_7745c5c3_Err != nil {
  884. return templ_7745c5c3_Err
  885. }
  886. if shardId < erasure_coding.DataShardsCount {
  887. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "<span class=\"badge badge-sm bg-primary ms-1\" style=\"font-size: 0.65rem;\" title=\"")
  888. if templ_7745c5c3_Err != nil {
  889. return templ_7745c5c3_Err
  890. }
  891. var templ_7745c5c3_Var36 string
  892. templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("Data shard %d", shardId))
  893. if templ_7745c5c3_Err != nil {
  894. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 411, Col: 173}
  895. }
  896. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
  897. if templ_7745c5c3_Err != nil {
  898. return templ_7745c5c3_Err
  899. }
  900. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "\">")
  901. if templ_7745c5c3_Err != nil {
  902. return templ_7745c5c3_Err
  903. }
  904. var templ_7745c5c3_Var37 string
  905. templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", shardId))
  906. if templ_7745c5c3_Err != nil {
  907. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 411, Col: 202}
  908. }
  909. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
  910. if templ_7745c5c3_Err != nil {
  911. return templ_7745c5c3_Err
  912. }
  913. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "</span>")
  914. if templ_7745c5c3_Err != nil {
  915. return templ_7745c5c3_Err
  916. }
  917. } else {
  918. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "<span class=\"badge badge-sm bg-warning text-dark ms-1\" style=\"font-size: 0.65rem;\" title=\"")
  919. if templ_7745c5c3_Err != nil {
  920. return templ_7745c5c3_Err
  921. }
  922. var templ_7745c5c3_Var38 string
  923. templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("Parity shard %d", shardId))
  924. if templ_7745c5c3_Err != nil {
  925. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 413, Col: 185}
  926. }
  927. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
  928. if templ_7745c5c3_Err != nil {
  929. return templ_7745c5c3_Err
  930. }
  931. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "\">")
  932. if templ_7745c5c3_Err != nil {
  933. return templ_7745c5c3_Err
  934. }
  935. var templ_7745c5c3_Var39 string
  936. templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("P%d", shardId-erasure_coding.DataShardsCount))
  937. if templ_7745c5c3_Err != nil {
  938. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 413, Col: 246}
  939. }
  940. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
  941. if templ_7745c5c3_Err != nil {
  942. return templ_7745c5c3_Err
  943. }
  944. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "</span>")
  945. if templ_7745c5c3_Err != nil {
  946. return templ_7745c5c3_Err
  947. }
  948. }
  949. }
  950. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "</small>")
  951. if templ_7745c5c3_Err != nil {
  952. return templ_7745c5c3_Err
  953. }
  954. }
  955. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "</div></div>")
  956. if templ_7745c5c3_Err != nil {
  957. return templ_7745c5c3_Err
  958. }
  959. }
  960. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "</div></div></div>")
  961. if templ_7745c5c3_Err != nil {
  962. return templ_7745c5c3_Err
  963. }
  964. }
  965. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "</div></div></div></div>")
  966. if templ_7745c5c3_Err != nil {
  967. return templ_7745c5c3_Err
  968. }
  969. }
  970. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "<!-- Worker Information Card -->")
  971. if templ_7745c5c3_Err != nil {
  972. return templ_7745c5c3_Err
  973. }
  974. if data.WorkerInfo != nil {
  975. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-server me-2\"></i> Worker Information</h5></div><div class=\"card-body\"><div class=\"row\"><div class=\"col-md-6\"><dl class=\"row\"><dt class=\"col-sm-4\">Worker ID:</dt><dd class=\"col-sm-8\"><code>")
  976. if templ_7745c5c3_Err != nil {
  977. return templ_7745c5c3_Err
  978. }
  979. var templ_7745c5c3_Var40 string
  980. templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(data.WorkerInfo.ID)
  981. if templ_7745c5c3_Err != nil {
  982. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 447, Col: 86}
  983. }
  984. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
  985. if templ_7745c5c3_Err != nil {
  986. return templ_7745c5c3_Err
  987. }
  988. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "</code></dd><dt class=\"col-sm-4\">Address:</dt><dd class=\"col-sm-8\"><code>")
  989. if templ_7745c5c3_Err != nil {
  990. return templ_7745c5c3_Err
  991. }
  992. var templ_7745c5c3_Var41 string
  993. templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(data.WorkerInfo.Address)
  994. if templ_7745c5c3_Err != nil {
  995. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 450, Col: 91}
  996. }
  997. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
  998. if templ_7745c5c3_Err != nil {
  999. return templ_7745c5c3_Err
  1000. }
  1001. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "</code></dd><dt class=\"col-sm-4\">Status:</dt><dd class=\"col-sm-8\">")
  1002. if templ_7745c5c3_Err != nil {
  1003. return templ_7745c5c3_Err
  1004. }
  1005. if data.WorkerInfo.Status == "active" {
  1006. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "<span class=\"badge bg-success\">Active</span>")
  1007. if templ_7745c5c3_Err != nil {
  1008. return templ_7745c5c3_Err
  1009. }
  1010. } else if data.WorkerInfo.Status == "busy" {
  1011. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<span class=\"badge bg-warning\">Busy</span>")
  1012. if templ_7745c5c3_Err != nil {
  1013. return templ_7745c5c3_Err
  1014. }
  1015. } else {
  1016. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<span class=\"badge bg-secondary\">Inactive</span>")
  1017. if templ_7745c5c3_Err != nil {
  1018. return templ_7745c5c3_Err
  1019. }
  1020. }
  1021. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "</dd></dl></div><div class=\"col-md-6\"><dl class=\"row\"><dt class=\"col-sm-4\">Last Heartbeat:</dt><dd class=\"col-sm-8\">")
  1022. if templ_7745c5c3_Err != nil {
  1023. return templ_7745c5c3_Err
  1024. }
  1025. var templ_7745c5c3_Var42 string
  1026. templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(data.WorkerInfo.LastHeartbeat.Format("2006-01-02 15:04:05"))
  1027. if templ_7745c5c3_Err != nil {
  1028. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 467, Col: 121}
  1029. }
  1030. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
  1031. if templ_7745c5c3_Err != nil {
  1032. return templ_7745c5c3_Err
  1033. }
  1034. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "</dd><dt class=\"col-sm-4\">Current Load:</dt><dd class=\"col-sm-8\">")
  1035. if templ_7745c5c3_Err != nil {
  1036. return templ_7745c5c3_Err
  1037. }
  1038. var templ_7745c5c3_Var43 string
  1039. templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d/%d", data.WorkerInfo.CurrentLoad, data.WorkerInfo.MaxConcurrent))
  1040. if templ_7745c5c3_Err != nil {
  1041. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 470, Col: 142}
  1042. }
  1043. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
  1044. if templ_7745c5c3_Err != nil {
  1045. return templ_7745c5c3_Err
  1046. }
  1047. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "</dd><dt class=\"col-sm-4\">Capabilities:</dt><dd class=\"col-sm-8\">")
  1048. if templ_7745c5c3_Err != nil {
  1049. return templ_7745c5c3_Err
  1050. }
  1051. for _, capability := range data.WorkerInfo.Capabilities {
  1052. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "<span class=\"badge bg-info me-1\">")
  1053. if templ_7745c5c3_Err != nil {
  1054. return templ_7745c5c3_Err
  1055. }
  1056. var templ_7745c5c3_Var44 string
  1057. templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(string(capability))
  1058. if templ_7745c5c3_Err != nil {
  1059. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 475, Col: 100}
  1060. }
  1061. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
  1062. if templ_7745c5c3_Err != nil {
  1063. return templ_7745c5c3_Err
  1064. }
  1065. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "</span>")
  1066. if templ_7745c5c3_Err != nil {
  1067. return templ_7745c5c3_Err
  1068. }
  1069. }
  1070. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</dd></dl></div></div></div></div></div></div>")
  1071. if templ_7745c5c3_Err != nil {
  1072. return templ_7745c5c3_Err
  1073. }
  1074. }
  1075. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<!-- Assignment History Card -->")
  1076. if templ_7745c5c3_Err != nil {
  1077. return templ_7745c5c3_Err
  1078. }
  1079. if len(data.AssignmentHistory) > 0 {
  1080. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "<div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-history me-2\"></i> Assignment History</h5></div><div class=\"card-body\"><div class=\"table-responsive\"><table class=\"table table-striped\"><thead><tr><th>Worker ID</th><th>Worker Address</th><th>Assigned At</th><th>Unassigned At</th><th>Reason</th></tr></thead> <tbody>")
  1081. if templ_7745c5c3_Err != nil {
  1082. return templ_7745c5c3_Err
  1083. }
  1084. for _, assignment := range data.AssignmentHistory {
  1085. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "<tr><td><code>")
  1086. if templ_7745c5c3_Err != nil {
  1087. return templ_7745c5c3_Err
  1088. }
  1089. var templ_7745c5c3_Var45 string
  1090. templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(assignment.WorkerID)
  1091. if templ_7745c5c3_Err != nil {
  1092. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 513, Col: 78}
  1093. }
  1094. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
  1095. if templ_7745c5c3_Err != nil {
  1096. return templ_7745c5c3_Err
  1097. }
  1098. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "</code></td><td><code>")
  1099. if templ_7745c5c3_Err != nil {
  1100. return templ_7745c5c3_Err
  1101. }
  1102. var templ_7745c5c3_Var46 string
  1103. templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(assignment.WorkerAddress)
  1104. if templ_7745c5c3_Err != nil {
  1105. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 514, Col: 83}
  1106. }
  1107. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
  1108. if templ_7745c5c3_Err != nil {
  1109. return templ_7745c5c3_Err
  1110. }
  1111. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "</code></td><td>")
  1112. if templ_7745c5c3_Err != nil {
  1113. return templ_7745c5c3_Err
  1114. }
  1115. var templ_7745c5c3_Var47 string
  1116. templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(assignment.AssignedAt.Format("2006-01-02 15:04:05"))
  1117. if templ_7745c5c3_Err != nil {
  1118. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 515, Col: 104}
  1119. }
  1120. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
  1121. if templ_7745c5c3_Err != nil {
  1122. return templ_7745c5c3_Err
  1123. }
  1124. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "</td><td>")
  1125. if templ_7745c5c3_Err != nil {
  1126. return templ_7745c5c3_Err
  1127. }
  1128. if assignment.UnassignedAt != nil {
  1129. var templ_7745c5c3_Var48 string
  1130. templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(assignment.UnassignedAt.Format("2006-01-02 15:04:05"))
  1131. if templ_7745c5c3_Err != nil {
  1132. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 518, Col: 110}
  1133. }
  1134. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
  1135. if templ_7745c5c3_Err != nil {
  1136. return templ_7745c5c3_Err
  1137. }
  1138. } else {
  1139. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "<span class=\"text-muted\">—</span>")
  1140. if templ_7745c5c3_Err != nil {
  1141. return templ_7745c5c3_Err
  1142. }
  1143. }
  1144. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "</td><td>")
  1145. if templ_7745c5c3_Err != nil {
  1146. return templ_7745c5c3_Err
  1147. }
  1148. var templ_7745c5c3_Var49 string
  1149. templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(assignment.Reason)
  1150. if templ_7745c5c3_Err != nil {
  1151. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 523, Col: 70}
  1152. }
  1153. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
  1154. if templ_7745c5c3_Err != nil {
  1155. return templ_7745c5c3_Err
  1156. }
  1157. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "</td></tr>")
  1158. if templ_7745c5c3_Err != nil {
  1159. return templ_7745c5c3_Err
  1160. }
  1161. }
  1162. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "</tbody></table></div></div></div></div></div>")
  1163. if templ_7745c5c3_Err != nil {
  1164. return templ_7745c5c3_Err
  1165. }
  1166. }
  1167. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "<!-- Execution Logs Card -->")
  1168. if templ_7745c5c3_Err != nil {
  1169. return templ_7745c5c3_Err
  1170. }
  1171. if len(data.ExecutionLogs) > 0 {
  1172. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "<div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-file-alt me-2\"></i> Execution Logs</h5></div><div class=\"card-body\"><div class=\"table-responsive\"><table class=\"table table-striped table-sm\"><thead><tr><th width=\"150\">Timestamp</th><th width=\"80\">Level</th><th>Message</th><th>Details</th></tr></thead> <tbody>")
  1173. if templ_7745c5c3_Err != nil {
  1174. return templ_7745c5c3_Err
  1175. }
  1176. for _, log := range data.ExecutionLogs {
  1177. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "<tr><td><small>")
  1178. if templ_7745c5c3_Err != nil {
  1179. return templ_7745c5c3_Err
  1180. }
  1181. var templ_7745c5c3_Var50 string
  1182. templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(log.Timestamp.Format("15:04:05"))
  1183. if templ_7745c5c3_Err != nil {
  1184. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 560, Col: 92}
  1185. }
  1186. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
  1187. if templ_7745c5c3_Err != nil {
  1188. return templ_7745c5c3_Err
  1189. }
  1190. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "</small></td><td>")
  1191. if templ_7745c5c3_Err != nil {
  1192. return templ_7745c5c3_Err
  1193. }
  1194. if log.Level == "error" {
  1195. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "<span class=\"badge bg-danger\">")
  1196. if templ_7745c5c3_Err != nil {
  1197. return templ_7745c5c3_Err
  1198. }
  1199. var templ_7745c5c3_Var51 string
  1200. templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(log.Level)
  1201. if templ_7745c5c3_Err != nil {
  1202. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 563, Col: 96}
  1203. }
  1204. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))
  1205. if templ_7745c5c3_Err != nil {
  1206. return templ_7745c5c3_Err
  1207. }
  1208. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "</span>")
  1209. if templ_7745c5c3_Err != nil {
  1210. return templ_7745c5c3_Err
  1211. }
  1212. } else if log.Level == "warn" {
  1213. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "<span class=\"badge bg-warning\">")
  1214. if templ_7745c5c3_Err != nil {
  1215. return templ_7745c5c3_Err
  1216. }
  1217. var templ_7745c5c3_Var52 string
  1218. templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(log.Level)
  1219. if templ_7745c5c3_Err != nil {
  1220. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 565, Col: 97}
  1221. }
  1222. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
  1223. if templ_7745c5c3_Err != nil {
  1224. return templ_7745c5c3_Err
  1225. }
  1226. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "</span>")
  1227. if templ_7745c5c3_Err != nil {
  1228. return templ_7745c5c3_Err
  1229. }
  1230. } else if log.Level == "info" {
  1231. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "<span class=\"badge bg-info\">")
  1232. if templ_7745c5c3_Err != nil {
  1233. return templ_7745c5c3_Err
  1234. }
  1235. var templ_7745c5c3_Var53 string
  1236. templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(log.Level)
  1237. if templ_7745c5c3_Err != nil {
  1238. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 567, Col: 94}
  1239. }
  1240. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
  1241. if templ_7745c5c3_Err != nil {
  1242. return templ_7745c5c3_Err
  1243. }
  1244. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</span>")
  1245. if templ_7745c5c3_Err != nil {
  1246. return templ_7745c5c3_Err
  1247. }
  1248. } else {
  1249. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "<span class=\"badge bg-secondary\">")
  1250. if templ_7745c5c3_Err != nil {
  1251. return templ_7745c5c3_Err
  1252. }
  1253. var templ_7745c5c3_Var54 string
  1254. templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(log.Level)
  1255. if templ_7745c5c3_Err != nil {
  1256. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 569, Col: 99}
  1257. }
  1258. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
  1259. if templ_7745c5c3_Err != nil {
  1260. return templ_7745c5c3_Err
  1261. }
  1262. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "</span>")
  1263. if templ_7745c5c3_Err != nil {
  1264. return templ_7745c5c3_Err
  1265. }
  1266. }
  1267. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "</td><td><code>")
  1268. if templ_7745c5c3_Err != nil {
  1269. return templ_7745c5c3_Err
  1270. }
  1271. var templ_7745c5c3_Var55 string
  1272. templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(log.Message)
  1273. if templ_7745c5c3_Err != nil {
  1274. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 572, Col: 70}
  1275. }
  1276. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
  1277. if templ_7745c5c3_Err != nil {
  1278. return templ_7745c5c3_Err
  1279. }
  1280. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "</code></td><td>")
  1281. if templ_7745c5c3_Err != nil {
  1282. return templ_7745c5c3_Err
  1283. }
  1284. if log.Fields != nil && len(log.Fields) > 0 {
  1285. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "<small>")
  1286. if templ_7745c5c3_Err != nil {
  1287. return templ_7745c5c3_Err
  1288. }
  1289. for _, k := range sortedKeys(log.Fields) {
  1290. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "<span class=\"badge bg-light text-dark me-1\">")
  1291. if templ_7745c5c3_Err != nil {
  1292. return templ_7745c5c3_Err
  1293. }
  1294. var templ_7745c5c3_Var56 string
  1295. templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(k)
  1296. if templ_7745c5c3_Err != nil {
  1297. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 577, Col: 110}
  1298. }
  1299. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
  1300. if templ_7745c5c3_Err != nil {
  1301. return templ_7745c5c3_Err
  1302. }
  1303. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "=<i>")
  1304. if templ_7745c5c3_Err != nil {
  1305. return templ_7745c5c3_Err
  1306. }
  1307. var templ_7745c5c3_Var57 string
  1308. templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(log.Fields[k])
  1309. if templ_7745c5c3_Err != nil {
  1310. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 577, Col: 129}
  1311. }
  1312. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
  1313. if templ_7745c5c3_Err != nil {
  1314. return templ_7745c5c3_Err
  1315. }
  1316. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "</i></span>")
  1317. if templ_7745c5c3_Err != nil {
  1318. return templ_7745c5c3_Err
  1319. }
  1320. }
  1321. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "</small>")
  1322. if templ_7745c5c3_Err != nil {
  1323. return templ_7745c5c3_Err
  1324. }
  1325. } else if log.Progress != nil || log.Status != "" {
  1326. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "<small>")
  1327. if templ_7745c5c3_Err != nil {
  1328. return templ_7745c5c3_Err
  1329. }
  1330. if log.Progress != nil {
  1331. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "<span class=\"badge bg-secondary me-1\">progress=<i>")
  1332. if templ_7745c5c3_Err != nil {
  1333. return templ_7745c5c3_Err
  1334. }
  1335. var templ_7745c5c3_Var58 string
  1336. templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.0f%%", *log.Progress))
  1337. if templ_7745c5c3_Err != nil {
  1338. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 583, Col: 151}
  1339. }
  1340. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
  1341. if templ_7745c5c3_Err != nil {
  1342. return templ_7745c5c3_Err
  1343. }
  1344. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "</i></span> ")
  1345. if templ_7745c5c3_Err != nil {
  1346. return templ_7745c5c3_Err
  1347. }
  1348. }
  1349. if log.Status != "" {
  1350. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "<span class=\"badge bg-secondary\">status=<i>")
  1351. if templ_7745c5c3_Err != nil {
  1352. return templ_7745c5c3_Err
  1353. }
  1354. var templ_7745c5c3_Var59 string
  1355. templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(log.Status)
  1356. if templ_7745c5c3_Err != nil {
  1357. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 586, Col: 118}
  1358. }
  1359. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))
  1360. if templ_7745c5c3_Err != nil {
  1361. return templ_7745c5c3_Err
  1362. }
  1363. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, "</i></span>")
  1364. if templ_7745c5c3_Err != nil {
  1365. return templ_7745c5c3_Err
  1366. }
  1367. }
  1368. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "</small>")
  1369. if templ_7745c5c3_Err != nil {
  1370. return templ_7745c5c3_Err
  1371. }
  1372. } else {
  1373. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "<span class=\"text-muted\">-</span>")
  1374. if templ_7745c5c3_Err != nil {
  1375. return templ_7745c5c3_Err
  1376. }
  1377. }
  1378. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "</td></tr>")
  1379. if templ_7745c5c3_Err != nil {
  1380. return templ_7745c5c3_Err
  1381. }
  1382. }
  1383. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "</tbody></table></div></div></div></div></div>")
  1384. if templ_7745c5c3_Err != nil {
  1385. return templ_7745c5c3_Err
  1386. }
  1387. }
  1388. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "<!-- Related Tasks Card -->")
  1389. if templ_7745c5c3_Err != nil {
  1390. return templ_7745c5c3_Err
  1391. }
  1392. if len(data.RelatedTasks) > 0 {
  1393. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "<div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-link me-2\"></i> Related Tasks</h5></div><div class=\"card-body\"><div class=\"table-responsive\"><table class=\"table table-striped\"><thead><tr><th>Task ID</th><th>Type</th><th>Status</th><th>Volume ID</th><th>Server</th><th>Created</th></tr></thead> <tbody>")
  1394. if templ_7745c5c3_Err != nil {
  1395. return templ_7745c5c3_Err
  1396. }
  1397. for _, relatedTask := range data.RelatedTasks {
  1398. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "<tr><td><a href=\"")
  1399. if templ_7745c5c3_Err != nil {
  1400. return templ_7745c5c3_Err
  1401. }
  1402. var templ_7745c5c3_Var60 templ.SafeURL
  1403. templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinURLErrs(fmt.Sprintf("/maintenance/tasks/%s", relatedTask.ID))
  1404. if templ_7745c5c3_Err != nil {
  1405. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 632, Col: 113}
  1406. }
  1407. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60))
  1408. if templ_7745c5c3_Err != nil {
  1409. return templ_7745c5c3_Err
  1410. }
  1411. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "\"><code>")
  1412. if templ_7745c5c3_Err != nil {
  1413. return templ_7745c5c3_Err
  1414. }
  1415. var templ_7745c5c3_Var61 string
  1416. templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(relatedTask.ID)
  1417. if templ_7745c5c3_Err != nil {
  1418. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 633, Col: 77}
  1419. }
  1420. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
  1421. if templ_7745c5c3_Err != nil {
  1422. return templ_7745c5c3_Err
  1423. }
  1424. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "</code></a></td><td><span class=\"badge bg-info\">")
  1425. if templ_7745c5c3_Err != nil {
  1426. return templ_7745c5c3_Err
  1427. }
  1428. var templ_7745c5c3_Var62 string
  1429. templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(string(relatedTask.Type))
  1430. if templ_7745c5c3_Err != nil {
  1431. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 636, Col: 105}
  1432. }
  1433. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
  1434. if templ_7745c5c3_Err != nil {
  1435. return templ_7745c5c3_Err
  1436. }
  1437. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "</span></td><td>")
  1438. if templ_7745c5c3_Err != nil {
  1439. return templ_7745c5c3_Err
  1440. }
  1441. if relatedTask.Status == maintenance.TaskStatusCompleted {
  1442. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "<span class=\"badge bg-success\">Completed</span>")
  1443. if templ_7745c5c3_Err != nil {
  1444. return templ_7745c5c3_Err
  1445. }
  1446. } else if relatedTask.Status == maintenance.TaskStatusFailed {
  1447. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "<span class=\"badge bg-danger\">Failed</span>")
  1448. if templ_7745c5c3_Err != nil {
  1449. return templ_7745c5c3_Err
  1450. }
  1451. } else if relatedTask.Status == maintenance.TaskStatusInProgress {
  1452. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "<span class=\"badge bg-warning\">In Progress</span>")
  1453. if templ_7745c5c3_Err != nil {
  1454. return templ_7745c5c3_Err
  1455. }
  1456. } else {
  1457. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "<span class=\"badge bg-secondary\">")
  1458. if templ_7745c5c3_Err != nil {
  1459. return templ_7745c5c3_Err
  1460. }
  1461. var templ_7745c5c3_Var63 string
  1462. templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(string(relatedTask.Status))
  1463. if templ_7745c5c3_Err != nil {
  1464. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 645, Col: 116}
  1465. }
  1466. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
  1467. if templ_7745c5c3_Err != nil {
  1468. return templ_7745c5c3_Err
  1469. }
  1470. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "</span>")
  1471. if templ_7745c5c3_Err != nil {
  1472. return templ_7745c5c3_Err
  1473. }
  1474. }
  1475. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "</td><td>")
  1476. if templ_7745c5c3_Err != nil {
  1477. return templ_7745c5c3_Err
  1478. }
  1479. if relatedTask.VolumeID != 0 {
  1480. var templ_7745c5c3_Var64 string
  1481. templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", relatedTask.VolumeID))
  1482. if templ_7745c5c3_Err != nil {
  1483. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 650, Col: 96}
  1484. }
  1485. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))
  1486. if templ_7745c5c3_Err != nil {
  1487. return templ_7745c5c3_Err
  1488. }
  1489. } else {
  1490. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "<span class=\"text-muted\">-</span>")
  1491. if templ_7745c5c3_Err != nil {
  1492. return templ_7745c5c3_Err
  1493. }
  1494. }
  1495. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "</td><td>")
  1496. if templ_7745c5c3_Err != nil {
  1497. return templ_7745c5c3_Err
  1498. }
  1499. if relatedTask.Server != "" {
  1500. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "<code>")
  1501. if templ_7745c5c3_Err != nil {
  1502. return templ_7745c5c3_Err
  1503. }
  1504. var templ_7745c5c3_Var65 string
  1505. templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(relatedTask.Server)
  1506. if templ_7745c5c3_Err != nil {
  1507. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 657, Col: 81}
  1508. }
  1509. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
  1510. if templ_7745c5c3_Err != nil {
  1511. return templ_7745c5c3_Err
  1512. }
  1513. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "</code>")
  1514. if templ_7745c5c3_Err != nil {
  1515. return templ_7745c5c3_Err
  1516. }
  1517. } else {
  1518. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "<span class=\"text-muted\">-</span>")
  1519. if templ_7745c5c3_Err != nil {
  1520. return templ_7745c5c3_Err
  1521. }
  1522. }
  1523. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "</td><td><small>")
  1524. if templ_7745c5c3_Err != nil {
  1525. return templ_7745c5c3_Err
  1526. }
  1527. var templ_7745c5c3_Var66 string
  1528. templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(relatedTask.CreatedAt.Format("2006-01-02 15:04:05"))
  1529. if templ_7745c5c3_Err != nil {
  1530. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 662, Col: 111}
  1531. }
  1532. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
  1533. if templ_7745c5c3_Err != nil {
  1534. return templ_7745c5c3_Err
  1535. }
  1536. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 192, "</small></td></tr>")
  1537. if templ_7745c5c3_Err != nil {
  1538. return templ_7745c5c3_Err
  1539. }
  1540. }
  1541. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 193, "</tbody></table></div></div></div></div></div>")
  1542. if templ_7745c5c3_Err != nil {
  1543. return templ_7745c5c3_Err
  1544. }
  1545. }
  1546. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 194, "<!-- Actions Card --><div class=\"row mb-4\"><div class=\"col-12\"><div class=\"card\"><div class=\"card-header\"><h5 class=\"mb-0\"><i class=\"fas fa-cogs me-2\"></i> Actions</h5></div><div class=\"card-body\">")
  1547. if templ_7745c5c3_Err != nil {
  1548. return templ_7745c5c3_Err
  1549. }
  1550. if data.Task.Status == maintenance.TaskStatusPending || data.Task.Status == maintenance.TaskStatusAssigned {
  1551. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 195, "<button type=\"button\" class=\"btn btn-danger me-2\" data-task-id=\"")
  1552. if templ_7745c5c3_Err != nil {
  1553. return templ_7745c5c3_Err
  1554. }
  1555. var templ_7745c5c3_Var67 string
  1556. templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ID)
  1557. if templ_7745c5c3_Err != nil {
  1558. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 686, Col: 104}
  1559. }
  1560. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67))
  1561. if templ_7745c5c3_Err != nil {
  1562. return templ_7745c5c3_Err
  1563. }
  1564. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 196, "\" onclick=\"cancelTask(this.getAttribute('data-task-id'))\"><i class=\"fas fa-times me-1\"></i> Cancel Task</button> ")
  1565. if templ_7745c5c3_Err != nil {
  1566. return templ_7745c5c3_Err
  1567. }
  1568. }
  1569. if data.Task.WorkerID != "" {
  1570. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 197, "<button type=\"button\" class=\"btn btn-primary me-2\" data-task-id=\"")
  1571. if templ_7745c5c3_Err != nil {
  1572. return templ_7745c5c3_Err
  1573. }
  1574. var templ_7745c5c3_Var68 string
  1575. templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ID)
  1576. if templ_7745c5c3_Err != nil {
  1577. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 692, Col: 105}
  1578. }
  1579. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
  1580. if templ_7745c5c3_Err != nil {
  1581. return templ_7745c5c3_Err
  1582. }
  1583. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 198, "\" data-worker-id=\"")
  1584. if templ_7745c5c3_Err != nil {
  1585. return templ_7745c5c3_Err
  1586. }
  1587. var templ_7745c5c3_Var69 string
  1588. templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.WorkerID)
  1589. if templ_7745c5c3_Err != nil {
  1590. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 692, Col: 141}
  1591. }
  1592. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
  1593. if templ_7745c5c3_Err != nil {
  1594. return templ_7745c5c3_Err
  1595. }
  1596. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 199, "\" onclick=\"showTaskLogs(this.getAttribute('data-task-id'), this.getAttribute('data-worker-id'))\"><i class=\"fas fa-file-text me-1\"></i> Show Task Logs</button> ")
  1597. if templ_7745c5c3_Err != nil {
  1598. return templ_7745c5c3_Err
  1599. }
  1600. }
  1601. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 200, "<button type=\"button\" class=\"btn btn-info\" data-task-id=\"")
  1602. if templ_7745c5c3_Err != nil {
  1603. return templ_7745c5c3_Err
  1604. }
  1605. var templ_7745c5c3_Var70 string
  1606. templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(data.Task.ID)
  1607. if templ_7745c5c3_Err != nil {
  1608. return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/task_detail.templ`, Line: 697, Col: 93}
  1609. }
  1610. _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
  1611. if templ_7745c5c3_Err != nil {
  1612. return templ_7745c5c3_Err
  1613. }
  1614. templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 201, "\" onclick=\"exportTaskDetail(this.getAttribute('data-task-id'))\"><i class=\"fas fa-download me-1\"></i> Export Details</button></div></div></div></div></div><!-- Task Logs Modal --><div class=\"modal fade\" id=\"taskLogsModal\" tabindex=\"-1\" aria-labelledby=\"taskLogsModalLabel\" aria-hidden=\"true\"><div class=\"modal-dialog modal-xl\"><div class=\"modal-content\"><div class=\"modal-header\"><h5 class=\"modal-title\" id=\"taskLogsModalLabel\"><i class=\"fas fa-file-text me-2\"></i>Task Logs</h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div><div class=\"modal-body\"><div id=\"logsLoadingSpinner\" class=\"text-center py-4\" style=\"display: none;\"><div class=\"spinner-border text-primary\" role=\"status\"><span class=\"visually-hidden\">Loading logs...</span></div><p class=\"mt-2\">Fetching logs from worker...</p></div><div id=\"logsError\" class=\"alert alert-danger\" style=\"display: none;\"><i class=\"fas fa-exclamation-triangle me-2\"></i> <span id=\"logsErrorMessage\"></span></div><div id=\"logsContent\" style=\"display: none;\"><div class=\"d-flex justify-content-between align-items-center mb-3\"><div><strong>Task:</strong> <span id=\"logsTaskId\"></span> | <strong>Worker:</strong> <span id=\"logsWorkerId\"></span> | <strong>Entries:</strong> <span id=\"logsCount\"></span></div><div class=\"btn-group\"><button type=\"button\" class=\"btn btn-sm btn-outline-primary\" onclick=\"refreshModalLogs()\"><i class=\"fas fa-sync-alt me-1\"></i>Refresh</button> <button type=\"button\" class=\"btn btn-sm btn-outline-success\" onclick=\"downloadTaskLogs()\"><i class=\"fas fa-download me-1\"></i>Download</button></div></div><div class=\"card\"><div class=\"card-header\"><div class=\"d-flex justify-content-between align-items-center\"><span>Log Entries (Last 100)</span> <small class=\"text-muted\">Newest entries first</small></div></div><div class=\"card-body p-0\"><pre id=\"logsDisplay\" class=\"bg-dark text-light p-3 mb-0\" style=\"max-height: 400px; overflow-y: auto; font-size: 0.85rem; line-height: 1.4;\"></pre></div></div></div></div><div class=\"modal-footer\"><button type=\"button\" class=\"btn btn-secondary\" data-bs-dismiss=\"modal\">Close</button></div></div></div></div><style>\n .timeline-container {\n position: relative;\n padding: 20px 0;\n }\n \n .timeline-progress {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n position: relative;\n max-width: 100%;\n }\n \n .timeline-step {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n position: relative;\n }\n \n .timeline-circle {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-weight: bold;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n z-index: 2;\n position: relative;\n }\n \n .timeline-circle.completed {\n background-color: #28a745;\n border: 3px solid #1e7e34;\n }\n \n .timeline-circle.pending {\n background-color: #6c757d;\n border: 3px solid #495057;\n }\n \n .timeline-connector {\n position: absolute;\n top: 20px;\n left: 50%;\n right: -50%;\n height: 4px;\n z-index: 1;\n margin-left: 20px;\n margin-right: 20px;\n }\n \n .timeline-connector.completed {\n background-color: #28a745;\n }\n \n .timeline-connector:not(.completed) {\n background-color: #dee2e6;\n }\n \n .timeline-step:last-child .timeline-connector {\n display: none;\n }\n \n .timeline-label {\n margin-top: 15px;\n text-align: center;\n min-height: 60px;\n }\n \n .timeline-label strong {\n display: block;\n font-size: 0.9rem;\n margin-bottom: 4px;\n }\n \n .timeline-label small {\n font-size: 0.75rem;\n line-height: 1.2;\n }\n \n @media (max-width: 768px) {\n .timeline-progress {\n flex-direction: column;\n align-items: stretch;\n }\n \n .timeline-step {\n flex-direction: row;\n align-items: center;\n margin-bottom: 20px;\n }\n \n .timeline-circle {\n margin-right: 15px;\n flex-shrink: 0;\n }\n \n .timeline-connector {\n display: none;\n }\n \n .timeline-label {\n text-align: left;\n margin-top: 0;\n min-height: auto;\n }\n }\n </style><script>\n // Global variables for current logs modal\n let currentTaskId = '';\n let currentWorkerId = '';\n\n function refreshPage() {\n location.reload();\n }\n\n function showTaskLogs(taskId, workerId) {\n currentTaskId = taskId;\n currentWorkerId = workerId;\n \n // Show the modal\n const modal = new bootstrap.Modal(document.getElementById('taskLogsModal'));\n modal.show();\n \n // Load logs\n loadTaskLogs(taskId, workerId);\n }\n\n function loadTaskLogs(taskId, workerId) {\n // Show loading spinner\n document.getElementById('logsLoadingSpinner').style.display = 'block';\n document.getElementById('logsError').style.display = 'none';\n document.getElementById('logsContent').style.display = 'none';\n \n // Update modal info\n document.getElementById('logsTaskId').textContent = taskId;\n document.getElementById('logsWorkerId').textContent = workerId;\n \n // Fetch logs from the API\n fetch(`/api/maintenance/workers/${workerId}/logs?taskId=${taskId}&maxEntries=100`)\n .then(response => response.json())\n .then(data => {\n document.getElementById('logsLoadingSpinner').style.display = 'none';\n \n if (data.error) {\n showLogsError(data.error);\n return;\n }\n \n // Display logs\n displayLogs(data.logs, data.count || 0);\n })\n .catch(error => {\n document.getElementById('logsLoadingSpinner').style.display = 'none';\n showLogsError('Failed to fetch logs: ' + error.message);\n });\n }\n\n function displayLogs(logs, count) {\n document.getElementById('logsError').style.display = 'none';\n document.getElementById('logsContent').style.display = 'block';\n document.getElementById('logsCount').textContent = count;\n \n const logsDisplay = document.getElementById('logsDisplay');\n \n if (!logs || logs.length === 0) {\n logsDisplay.textContent = 'No logs found for this task.';\n return;\n }\n \n // Format and display logs with structured fields\n let logText = '';\n logs.forEach(entry => {\n const timestamp = entry.timestamp ? new Date(entry.timestamp * 1000).toISOString() : 'N/A';\n const level = entry.level || 'INFO';\n const message = entry.message || '';\n \n logText += `[${timestamp}] ${level}: ${message}`;\n \n // Add structured fields if they exist\n if (entry.fields && Object.keys(entry.fields).length > 0) {\n const fieldsStr = Object.entries(entry.fields)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n logText += ` | ${fieldsStr}`;\n }\n \n // Add progress if available\n if (entry.progress !== undefined && entry.progress !== null) {\n logText += ` | progress=${entry.progress}%`;\n }\n \n // Add status if available\n if (entry.status) {\n logText += ` | status=${entry.status}`;\n }\n \n logText += '\\n';\n });\n \n logsDisplay.textContent = logText;\n \n // Scroll to top\n logsDisplay.scrollTop = 0;\n }\n\n function showLogsError(errorMessage) {\n document.getElementById('logsError').style.display = 'block';\n document.getElementById('logsContent').style.display = 'none';\n document.getElementById('logsErrorMessage').textContent = errorMessage;\n }\n\n function refreshModalLogs() {\n if (currentTaskId && currentWorkerId) {\n loadTaskLogs(currentTaskId, currentWorkerId);\n }\n }\n\n function downloadTaskLogs() {\n if (!currentTaskId || !currentWorkerId) {\n alert('No task logs to download');\n return;\n }\n \n // Download all logs (without maxEntries limit)\n const downloadUrl = `/api/maintenance/workers/${currentWorkerId}/logs?taskId=${currentTaskId}&maxEntries=0`;\n \n fetch(downloadUrl)\n .then(response => response.json())\n .then(data => {\n if (data.error) {\n alert('Error downloading logs: ' + data.error);\n return;\n }\n \n // Convert logs to text format with structured fields\n let logContent = '';\n if (data.logs && data.logs.length > 0) {\n data.logs.forEach(entry => {\n const timestamp = entry.timestamp ? new Date(entry.timestamp * 1000).toISOString() : 'N/A';\n const level = entry.level || 'INFO';\n const message = entry.message || '';\n \n logContent += `[${timestamp}] ${level}: ${message}`;\n \n // Add structured fields if they exist\n if (entry.fields && Object.keys(entry.fields).length > 0) {\n const fieldsStr = Object.entries(entry.fields)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n logContent += ` | ${fieldsStr}`;\n }\n \n // Add progress if available\n if (entry.progress !== undefined && entry.progress !== null) {\n logContent += ` | progress=${entry.progress}%`;\n }\n \n // Add status if available\n if (entry.status) {\n logContent += ` | status=${entry.status}`;\n }\n \n logContent += '\\n';\n });\n } else {\n logContent = 'No logs found for this task.';\n }\n \n // Create and download file\n const blob = new Blob([logContent], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `task-${currentTaskId}-logs.txt`;\n link.click();\n URL.revokeObjectURL(url);\n })\n .catch(error => {\n alert('Error downloading logs: ' + error.message);\n });\n }\n\n function cancelTask(taskId) {\n if (confirm('Are you sure you want to cancel this task?')) {\n fetch(`/api/maintenance/tasks/${taskId}/cancel`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(response => response.json())\n .then(data => {\n if (data.success) {\n alert('Task cancelled successfully');\n location.reload();\n } else {\n alert('Error cancelling task: ' + data.error);\n }\n })\n .catch(error => {\n console.error('Error:', error);\n alert('Error cancelling task');\n });\n }\n }\n\n function refreshTaskLogs(taskId) {\n fetch(`/api/maintenance/tasks/${taskId}/detail`)\n .then(response => response.json())\n .then(data => {\n location.reload();\n })\n .catch(error => {\n console.error('Error:', error);\n alert('Error refreshing logs');\n });\n }\n\n function exportTaskDetail(taskId) {\n fetch(`/api/maintenance/tasks/${taskId}/detail`)\n .then(response => response.json())\n .then(data => {\n const dataStr = JSON.stringify(data, null, 2);\n const dataBlob = new Blob([dataStr], {type: 'application/json'});\n const url = URL.createObjectURL(dataBlob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `task-${taskId}-detail.json`;\n link.click();\n URL.revokeObjectURL(url);\n })\n .catch(error => {\n console.error('Error:', error);\n alert('Error exporting task detail');\n });\n }\n\n // Auto-refresh every 30 seconds for active tasks\n if ('{string(data.Task.Status)}' === 'in_progress') {\n setInterval(refreshPage, 30000);\n }\n </script>")
  1615. if templ_7745c5c3_Err != nil {
  1616. return templ_7745c5c3_Err
  1617. }
  1618. return nil
  1619. })
  1620. }
  1621. var _ = templruntime.GeneratedTemplate