fetch_ml/cmd/tui/internal/controller/settings.go
Jeremie Fraeys fb2bbbaae5
refactor: Phase 7 - TUI cleanup - reorganize model package
Phase 7 of the monorepo maintainability plan:

New files created:
- model/jobs.go - Job type, JobStatus constants, list.Item interface
- model/messages.go - tea.Msg types (JobsLoadedMsg, StatusMsg, TickMsg, etc.)
- model/styles.go - NewJobListDelegate(), JobListTitleStyle(), SpinnerStyle()
- model/keys.go - KeyMap struct, DefaultKeys() function

Modified files:
- model/state.go - reduced from 226 to ~130 lines
  - Removed: Job, JobStatus, KeyMap, Keys, inline styles
  - Kept: State struct, domain re-exports, ViewMode, DatasetInfo, InitialState()
- controller/commands.go - use model. prefix for message types
- controller/controller.go - use model. prefix for message types
- controller/settings.go - use model.SettingsContentMsg

Deleted files:
- controller/keys.go (moved to model/keys.go since State references KeyMap)

Result:
- No file >150 lines in model/ package
- Single concern per file: state, jobs, messages, styles, keys
- All 41 test packages pass
2026-02-17 20:22:04 -05:00

127 lines
3.4 KiB
Go

package controller
import (
"fmt"
"strings"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/jfraeys/fetch_ml/cmd/tui/internal/model"
)
// Settings-related command factories and handlers
func (c *Controller) updateSettingsContent(m model.State) tea.Cmd {
var content strings.Builder
// API Key Status section
statusStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.AdaptiveColor{Light: "#d8dee9", Dark: "#4c566a"}). // borderfg
Padding(0, 1).
Width(m.SettingsView.Width - 4)
if m.SettingsIndex == 0 {
statusStyle = statusStyle.
BorderForeground(lipgloss.AdaptiveColor{Light: "#3498db", Dark: "#7aa2f7"}) // activeBorderfg
}
statusContent := fmt.Sprintf("%s API Key Status\n%s",
getSettingsIndicator(m, 0),
getAPIKeyStatus(m))
content.WriteString(statusStyle.Render(statusContent))
content.WriteString("\n")
// API Key Input section
inputStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.AdaptiveColor{Light: "#d8dee9", Dark: "#4c566a"}).
Padding(0, 1).
Width(m.SettingsView.Width - 4)
if m.SettingsIndex == 1 {
inputStyle = inputStyle.
BorderForeground(lipgloss.AdaptiveColor{Light: "#3498db", Dark: "#7aa2f7"})
}
inputContent := fmt.Sprintf("%s Enter New API Key\n%s",
getSettingsIndicator(m, 1),
m.APIKeyInput.View())
content.WriteString(inputStyle.Render(inputContent))
content.WriteString("\n")
// Save Configuration section
saveStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.AdaptiveColor{Light: "#d8dee9", Dark: "#4c566a"}).
Padding(0, 1).
Width(m.SettingsView.Width - 4)
if m.SettingsIndex == 2 {
saveStyle = saveStyle.
BorderForeground(lipgloss.AdaptiveColor{Light: "#3498db", Dark: "#7aa2f7"})
}
saveContent := fmt.Sprintf("%s Save Configuration\n[Enter]",
getSettingsIndicator(m, 2))
content.WriteString(saveStyle.Render(saveContent))
content.WriteString("\n")
// Current API Key display
keyStyle := lipgloss.NewStyle().
Foreground(lipgloss.AdaptiveColor{Light: "#666", Dark: "#999"}).
Italic(true)
keyContent := fmt.Sprintf("Current API Key: %s", maskAPIKey(m.APIKey))
content.WriteString(keyStyle.Render(keyContent))
return func() tea.Msg { return model.SettingsContentMsg(content.String()) }
}
func (c *Controller) handleSettingsAction(m *model.State) tea.Cmd {
switch m.SettingsIndex {
case 0: // API Key Status - do nothing
return nil
case 1: // Enter New API Key - do nothing, Enter key disabled
return nil
case 2: // Save Configuration
switch {
case m.APIKeyInput.Value() != "":
m.APIKey = m.APIKeyInput.Value()
m.APIKeyInput.SetValue("")
m.Status = "Configuration saved (in-memory only)"
return c.updateSettingsContent(*m)
case m.APIKey != "":
m.Status = "Configuration saved (in-memory only)"
default:
m.ErrorMsg = "No API key to save"
}
}
return nil
}
// Helper functions for settings
func getSettingsIndicator(m model.State, index int) string {
if index == m.SettingsIndex {
return "▶"
}
return " "
}
func getAPIKeyStatus(m model.State) string {
if m.APIKey != "" {
return "✓ API Key is set\n" + maskAPIKey(m.APIKey)
}
return "⚠ No API Key configured"
}
func maskAPIKey(key string) string {
if key == "" {
return "(not set)"
}
if len(key) <= 8 {
return "****"
}
return key[:4] + "****" + key[len(key)-4:]
}