@@ -12,6 +12,7 @@ import (
"bytes"
"context"
"fmt"
"time"
"vetting/internal/model"
)
@@ -51,7 +52,7 @@ func HostTile(t TileData) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "host-%d" , t . Host . ID ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 15 , Col : 40 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 16 , Col : 40 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var3 ) )
if templ_7745c5c3_Err != nil {
@@ -77,7 +78,7 @@ func HostTile(t TileData) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "tile-%d" , t . Host . ID ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 17 , Col : 46 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 18 , Col : 46 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var5 ) )
if templ_7745c5c3_Err != nil {
@@ -90,228 +91,263 @@ func HostTile(t TileData) templ.Component {
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6 , templ_7745c5c3_Err = templ . JoinStringErrs ( t . Host . Name )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 21 , Col : 39 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 22 , Col : 39 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var6 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 5 , "</div><div class=\"tile-status \">" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 5 , "</div><div class=\"tile-header-right \">" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7 , templ_7745c5c3_Err = templ . JoinStringErrs ( tileStatus ( t . Latest ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 22 , Col : 50 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var7 ) )
var templ_7745c5c3_Var7 = [ ] any { "tile-last-seen" , lastSeenClass ( t . LastSeenAt ) }
templ_7745c5c3_Err = templ . RenderCSSItems ( ctx , templ_7745c5c3_Buffer , templ_7745c5c3_Var7 ... )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 6 , "</div></header><dl class=\"tile-meta\"><div><dt>MAC</dt><dd> " )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 6 , "<span class=\" " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8 , templ_7745c5c3_Err = templ . JoinStringErrs ( t . Host . MAC )
templ_7745c5c3_Var8 , templ_7745c5c3_Err = templ . JoinStringErrs ( templ . CSSClasses ( templ_7745c5c3_Var7 ) . String ( ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 27 , Col : 20 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 1 , Col : 0 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var8 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 7 , "</dd></div><div><dt>WoL</dt><dd >" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 7 , "\" >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "%s:%d" , t . Host . WoLBroadcastIP , t . Host . WoLPort ) )
templ_7745c5c3_Var9 , templ_7745c5c3_Err = templ . JoinStringErrs ( lastSeenLabel ( t . LastSeenAt ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 31 , Col : 69 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 24 , Col : 95 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var9 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 8 , "</dd ></ div>" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 8 , "</span ><div class=\"tile-status\" >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10 , templ_7745c5c3_Err = templ . JoinStringErrs ( tileStatus ( t . Latest ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 25 , Col : 51 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var10 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 9 , "</div></div></header><dl class=\"tile-meta\"><div><dt>MAC</dt><dd>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11 , templ_7745c5c3_Err = templ . JoinStringErrs ( t . Host . MAC )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 31 , Col : 20 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var11 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 10 , "</dd></div><div><dt>WoL</dt><dd>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "%s:%d" , t . Host . WoLBroadcastIP , t . Host . WoLPort ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 35 , Col : 69 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var12 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 11 , "</dd></div>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if t . Latest != nil && t . Latest . FailedStage != "" {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 9 , "<div><dt>Failed at</dt><dd>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10 , templ_7745c5c3_Err = templ . JoinStringErrs ( t . Latest . FailedStage )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 36 , Col : 31 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var10 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 10 , "</dd></div>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if t . SpecDiffCritical > 0 {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 11 , "<div><dt>Spec diffs</dt><dd class=\"bad\">" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "%d critical" , t . SpecDiffCritical ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 42 , Col : 69 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var11 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 12 , "</dd></div>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 13 , "</dl>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if t . Latest != nil && t . Latest . State == model . StateFailedHolding && t . Latest . HoldIP != "" {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 14 , "<div class=\"tile-hold\"><div class=\"hold-title\">Host is holding — SSH available</div><code class=\"hold-ssh\">" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12 , templ_7745c5c3_Err = templ . JoinStringErrs ( sshInvocation ( t . HoldKeyPath , t . Latest . HoldIP ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 49 , Col : 74 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var12 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 15 , "</code></div>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if t . Latest != nil {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 16 , "<div class=\"tile-log\" id=\"" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 12 , "<div><dt>Failed at</dt><dd>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "log-%d" , t . Latest . ID ) )
templ_7745c5c3_Var13 , templ_7745c5c3_Err = templ . JoinStringErrs ( t . Latest . FailedStage )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 55 , Col : 43 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 40 , Col : 31 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var13 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 17 , "\" sse-swap=\" " )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 13 , "</dd></div> " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if t . SpecDiffCritical > 0 {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 14 , "<div><dt>Spec diffs</dt><dd class=\"bad\">" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "log-%d " , t . Latest . ID ) )
templ_7745c5c3_Var14 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "%d critical " , t . SpecDiffCritical ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 56 , Col : 49 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 46 , Col : 69 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var14 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 18 , "\" hx-swap=\"beforeend\" ></div>" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 15 , "</dd ></div>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 19 , "<div class=\"tile-actions\" >" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 16 , "</dl >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if canStart ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 20 , "<form method=\"post\" action=\" " )
if t . Latest != nil && t . Latest . State == model . StateFailedHolding && t . Latest . HoldIP != "" {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 17 , "<div class=\"tile-hold\"><div class=\"hold-title\">Host is holding — SSH available</div><code class=\"hold-ssh\"> " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 templ . SafeURL
templ_7745c5c3_Var15 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/start" , t . Host . ID ) ) )
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15 , templ_7745c5c3_Err = templ . JoinStringErrs ( sshInvocation ( t . HoldKeyPath , t . Latest . HoldIP ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 62 , Col : 89 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 53 , Col : 74 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var15 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 21 , "\" class=\"inline\"><button type=\"submit\">Start vetting</button></form >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 22 , "<button type=\"button\" disabled>Run in flight</button> " )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 18 , "</code></div >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if canOverrideWipe ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 23 , "<form method=\"post\" action =\"" )
if t . Latest != nil {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 19 , "<div class=\"tile-log\" id =\"" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 templ . SafeURL
templ_7745c5c3_Var16 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/override-wipe " , t . Host . ID ) ) )
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "log-%d " , t . Latest . ID ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 69 , Col : 97 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 59 , Col : 43 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var16 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 24 , "\" class=\"inline\"><button type=\"submit\" class=\"danger\">Override wipe-probe</button></form> " )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 20 , "\" sse-swap=\" " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if hasReport ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 25 , "<a class=\"button-like\" href=\"" )
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17 , templ_7745c5c3_Err = templ . JoinStringErrs ( fmt . Sprintf ( "log-%d" , t . Latest . ID ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 templ . SafeURL
templ_7745c5c3_Var17 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/reports/%d" , t . Latest . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 74 , Col : 88 }
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 60 , Col : 49 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var17 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 26 , "\" target=\"_blank\" rel=\"noopener\">View report</a >" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 21 , "\" hx-swap=\"beforeend\"></div >" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 27 , "<form method=\"post\" action= \"" )
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 22 , "<div class=\"tile- actions \"> " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 templ . SafeURL
templ_7745c5c3_Var18 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/delete" , t . Host . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 76 , Col : 89 }
if canStart ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 23 , "<form method=\"post\" action=\"" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 templ . SafeURL
templ_7745c5c3_Var18 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/start" , t . Host . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 66 , Col : 89 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var18 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 24 , "\" class=\"inline\"><button type=\"submit\">Start vetting</button></form>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 25 , "<button type=\"button\" disabled>Run in flight</button> " )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var18 ) )
if canOverrideWipe ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 26 , "<form method=\"post\" action=\"" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 templ . SafeURL
templ_7745c5c3_Var19 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/override-wipe" , t . Host . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 73 , Col : 97 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var19 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 27 , "\" class=\"inline\"><button type=\"submit\" class=\"danger\">Override wipe-probe</button></form>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if hasReport ( t . Latest ) {
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 28 , "<a class=\"button-like\" href=\"" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 templ . SafeURL
templ_7745c5c3_Var20 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/reports/%d" , t . Latest . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 78 , Col : 88 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var20 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 29 , "\" target=\"_blank\" rel=\"noopener\">View report</a>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 30 , "<form method=\"post\" action=\"" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 28 , "\" class=\"inline\"><button type=\"submit\" class=\"danger\">Delete</button></form></div></article>" )
var templ_7745c5c3_Var21 templ . SafeURL
templ_7745c5c3_Var21 , templ_7745c5c3_Err = templ . JoinURLErrs ( templ . SafeURL ( fmt . Sprintf ( "/hosts/%d/delete" , t . Host . ID ) ) )
if templ_7745c5c3_Err != nil {
return templ . Error { Err : templ_7745c5c3_Err , FileName : ` host_tile.templ ` , Line : 80 , Col : 89 }
}
_ , templ_7745c5c3_Err = templ_7745c5c3_Buffer . WriteString ( templ . EscapeString ( templ_7745c5c3_Var21 ) )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime . WriteString ( templ_7745c5c3_Buffer , 31 , "\" class=\"inline\"><button type=\"submit\" class=\"danger\">Delete</button></form></div></article>" )
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -382,4 +418,47 @@ func RenderTileString(t TileData) string {
return buf . String ( )
}
// lastSeenLabel renders the host-mode agent's liveness into a short
// badge: "never" if the host has never heartbeated, "online" within
// a 2× heartbeat grace window (60s, since agents heartbeat every 30s),
// "Nm ago" / "Nh ago" / "Nd ago" otherwise.
func lastSeenLabel ( t * time . Time ) string {
if t == nil {
return "never"
}
return humanAgoFrom ( time . Now ( ) , * t )
}
// lastSeenClass pairs with lastSeenLabel to drive the badge color
// without the template having to carry its own logic.
func lastSeenClass ( t * time . Time ) string {
if t == nil {
return "offline"
}
if time . Since ( * t ) < 60 * time . Second {
return "online"
}
return "stale"
}
// humanAgoFrom formats (now - t) as a short "Nm ago" style string.
// Buckets: <60s -> "online", <60m -> minutes, <24h -> hours, else days.
// Split on `now` so callers can hold time for tests.
func humanAgoFrom ( now time . Time , t time . Time ) string {
d := now . Sub ( t )
if d < 0 {
d = 0
}
if d < 60 * time . Second {
return "online"
}
if d < time . Hour {
return fmt . Sprintf ( "%dm ago" , int ( d / time . Minute ) )
}
if d < 24 * time . Hour {
return fmt . Sprintf ( "%dh ago" , int ( d / time . Hour ) )
}
return fmt . Sprintf ( "%dd ago" , int ( d / ( 24 * time . Hour ) ) )
}
var _ = templruntime . GeneratedTemplate