Version final

This commit is contained in:
luisgulo committed 2026-10-31 18:32:28 +01:00
1 parent 2d4b09b9ea
commit 74b7a0c448
13 files changed
+1103 -7

No files matched your search

+179
View File
@@ -0,0 +1,179 @@
package ui
import (
"registry-tui/client"
"sort"
"strings"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)
type ViewState int
const (
StateLoading ViewState = iota
StateMainTable
StateConfirmDelete
StateNewTag
StateError
StateRegistryDown
)
type AppMode int
const (
ModeRegistry AppMode = iota
ModeLocal
)
type ImageRow = client.ImageRowData
type Model struct {
state ViewState
mode AppMode
client *client.RegistryClient
rows []ImageRow
localRows []ImageRow
registryRows []ImageRow
cursor int
err error
statusMsg string
textInput textinput.Model
version string
}
func NewModel(registryURL string, version string) Model {
ti := textinput.New()
ti.Placeholder = "ej. proyecto-web/alpine:v1.0"
ti.CharLimit = 128
ti.Width = 35
return Model{
state: StateLoading,
mode: ModeRegistry,
client: client.NewRegistryClient(registryURL),
textInput: ti,
version: version,
}
}
func (m Model) Init() tea.Cmd {
return fetchRegistryImagesCmd(m.client)
}
type imagesMsg struct {
rows []ImageRow
mode AppMode
}
type errorMsg error
type successMsg string
func fetchRegistryImagesCmd(c *client.RegistryClient) tea.Cmd {
return func() tea.Msg {
repos, err := c.GetCatalog()
if err != nil {
return errorMsg(err)
}
var rows []ImageRow
for _, repo := range repos {
tags, err := c.GetTags(repo)
if err != nil {
continue
}
var project, imageName string
parts := strings.Split(repo, "/")
if len(parts) > 1 {
project = parts[0]
imageName = strings.Join(parts[1:], "/")
} else {
project = ""
imageName = repo
}
for _, tag := range tags {
rows = append(rows, ImageRow{
Project: project,
RepoName: repo,
ImageName: imageName,
Tag: tag,
})
}
}
sortRows(rows)
return imagesMsg{rows: rows, mode: ModeRegistry}
}
}
func fetchLocalImagesCmd(c *client.RegistryClient) tea.Cmd {
return func() tea.Msg {
rows, err := c.GetLocalImages()
if err != nil {
return errorMsg(err)
}
sortRows(rows)
return imagesMsg{rows: rows, mode: ModeLocal}
}
}
func sortRows(rows []ImageRow) {
sort.Slice(rows, func(i, j int) bool {
if rows[i].Project == rows[j].Project {
return rows[i].RepoName < rows[j].RepoName
}
return rows[i].Project < rows[j].Project
})
}
func deleteTagCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
return func() tea.Msg {
err := c.DeleteManifest(repo, tag)
if err != nil {
return errorMsg(err)
}
return successMsg("Tag borrado con éxito del registro")
}
}
func deleteLocalImageCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
return func() tea.Msg {
err := c.DeleteLocalImage(repo, tag)
if err != nil {
return errorMsg(err)
}
return successMsg("Imagen local borrada con éxito")
}
}
func copyImageCmd(c *client.RegistryClient, sourceRepo, sourceTag, destRepo, destTag string) tea.Cmd {
return func() tea.Msg {
err := c.CopyManifest(sourceRepo, sourceTag, destRepo, destTag)
if err != nil {
return errorMsg(err)
}
return successMsg("Imagen reestructurada con éxito en el registro")
}
}
func tagLocalImageCmd(c *client.RegistryClient, sourceRepo, sourceTag, destRepo, destTag string) tea.Cmd {
return func() tea.Msg {
err := c.TagLocalImage(sourceRepo, sourceTag, destRepo, destTag)
if err != nil {
return errorMsg(err)
}
return successMsg("Imagen local etiquetada con éxito")
}
}
func pushImageCmd(c *client.RegistryClient, repo, tag string) tea.Cmd {
return func() tea.Msg {
err := c.PushLocalImage(repo, tag)
if err != nil {
return errorMsg(err)
}
return successMsg("Imagen subida (Push) al registro con éxito")
}
}