package main
import (
"strconv"
"strings"
)
func (m model) viewK3s() string {
var b strings.Builder
b.WriteString(row(stepGlyph(m.k3sDone, m.installErr), "[1/3] k3s", stepDetail(m.k3sDone)) + "\n")
b.WriteString(row(stepGlyph(m.certManagerDone, m.installErr), "[2/3] cert-manager", stepDetail(m.certManagerDone)) + "\n")
b.WriteString(row(stepGlyph(m.issuerDone, m.installErr), "[3/3] Émetteur Let's Encrypt", stepDetail(m.issuerDone)) + "\n")
if m.installErr != nil {
b.WriteString("\n" + styleDanger.Render("Erreur : "+m.installErr.Error()))
}
b.WriteString("\n\n" + styleLog.Render(tailLines(m.k3sLines, 8)))
return stylePanel.Render(b.String())
}
func (m model) viewBuild() string {
var b strings.Builder
b.WriteString(row(stepGlyph(m.buildDone, m.buildErr), "docker build", stepDetail(m.buildDone)) + "\n")
b.WriteString(row(stepGlyph(m.importDone, m.buildErr), "import dans containerd", stepDetail(m.importDone)) + "\n")
if m.buildErr != nil {
b.WriteString("\n" + styleDanger.Render("Erreur : "+m.buildErr.Error()))
}
b.WriteString("\n\n" + styleLog.Render(tailLines(m.buildLines, 10)))
b.WriteString("\n" + styleMuted.Render("Construit ici, sur cette machine — jamais copié depuis un poste de travail d'une autre architecture."))
return stylePanel.Render(b.String())
}
func (m model) viewDeploy() string {
var b strings.Builder
for i, f := range m.deployStatus {
g := glyph(statusMissing)
if f.Err != nil {
g = glyph(statusWarn)
} else if f.Done {
g = glyph(statusOK)
} else if i == m.deployIdx {
g = m.spin.View()
}
b.WriteString(row(g, shortManifestName(f.Label), "") + "\n")
}
if m.deployErr != nil {
b.WriteString("\n" + styleDanger.Render("Erreur : "+m.deployErr.Error()))
}
return stylePanel.Render(b.String())
}
func shortManifestName(path string) string {
if i := strings.LastIndex(path, "/"); i >= 0 {
return path[i+1:]
}
return path
}
func (m model) viewPodStatus() string {
var b strings.Builder
if m.pod.Name == "" {
b.WriteString(m.spin.View() + " " + styleBody.Render("En attente que le pod soit planifié…"))
if m.podErr != nil {
b.WriteString("\n\n" + styleWarn.Render("!") + " " + styleMuted.Render(m.podErr.Error()))
}
return stylePanel.Render(b.String())
}
ready := m.pod.Phase == podReady
g := m.spin.View()
if ready {
g = glyph(statusOK)
}
b.WriteString(row(g, m.pod.Name, itoaFrac(m.pod.ReadyContainers, m.pod.TotalContainers)+" "+m.pod.RawStatus) + "\n")
if ready {
b.WriteString(row(glyph(statusOK), "server — socket admin actif", "") + "\n")
b.WriteString(row(glyph(statusOK), "web — répond sur :8088", "") + "\n")
} else {
b.WriteString("\n" + styleMuted.Render("Un bref 0/2 juste après le déploiement est normal — web attend le socket admin de server."))
}
return stylePanel.Render(b.String())
}
func (m model) viewPodStuck() string {
var b strings.Builder
b.WriteString(row(glyph(statusWarn), m.pod.Name, itoaFrac(m.pod.ReadyContainers, m.pod.TotalContainers)+" "+m.pod.RawStatus) + "\n\n")
if !m.stuckDiagDone {
b.WriteString(m.spin.View() + " " + styleBody.Render("Comparaison des tags d'image…"))
return stylePanelDanger.Render(b.String())
}
diag := m.stuckDiag
b.WriteString(styleBold.Render("Ce que ça veut dire :") + " " +
styleBody.Render("l'image importée n'a pas le tag attendu par le déploiement.") + "\n\n")
b.WriteString(row("", "deployment.yaml attend", diag.Expected) + "\n")
if len(diag.Imported) == 0 {
b.WriteString(row(glyph(statusWarn), "images importées trouvées", "aucune") + "\n")
}
for _, tag := range diag.Imported {
g := glyph(statusMissing)
if tag == diag.Expected {
g = glyph(statusOK)
}
b.WriteString(row(g, "images importées trouvées", tag) + "\n")
}
b.WriteString("\n" + styleBody.Render("→ Reconstruire avec le bon tag corrige ça automatiquement (r)."))
return stylePanelDanger.Render(b.String())
}
func stepGlyph(done bool, err error) string {
if err != nil {
return glyph(statusWarn)
}
if done {
return glyph(statusOK)
}
return glyph(statusMissing)
}
func stepDetail(done bool) string {
if done {
return "prêt"
}
return ""
}
func tailLines(lines []string, n int) string {
if len(lines) == 0 {
return styleMuted.Render("(pas encore de sortie)")
}
if len(lines) > n {
lines = lines[len(lines)-n:]
}
return strings.Join(lines, "\n")
}
func itoaFrac(a, b int) string {
return strconv.Itoa(a) + "/" + strconv.Itoa(b)
}