v3.42.11: Replace all Unicode emojis with ASCII text
All checks were successful
CI/CD / Test (push) Successful in 1m13s
CI/CD / Lint (push) Successful in 1m20s
CI/CD / Build & Release (push) Successful in 3m10s

- Replace all emoji characters with ASCII equivalents throughout codebase
- Replace Unicode box-drawing characters (═║╔╗╚╝━─) with ASCII (+|-=)
- Replace checkmarks (✓✗) with [OK]/[FAIL] markers
- 59 files updated, 741 lines changed
- Improves terminal compatibility and reduces visual noise
This commit is contained in:
2026-01-08 09:42:01 +01:00
parent 5fb88b14ba
commit 3e41d88445
61 changed files with 1040 additions and 739 deletions

View File

@@ -209,12 +209,12 @@ func (m ArchiveBrowserModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Validate selection based on mode
if m.mode == "restore-cluster" && !selected.Format.IsClusterBackup() {
m.message = errorStyle.Render(" Please select a cluster backup (.tar.gz)")
m.message = errorStyle.Render("[FAIL] Please select a cluster backup (.tar.gz)")
return m, nil
}
if m.mode == "restore-single" && selected.Format.IsClusterBackup() {
m.message = errorStyle.Render(" Please select a single database backup")
m.message = errorStyle.Render("[FAIL] Please select a single database backup")
return m, nil
}
@@ -227,7 +227,7 @@ func (m ArchiveBrowserModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Show detailed info
if len(m.archives) > 0 && m.cursor < len(m.archives) {
selected := m.archives[m.cursor]
m.message = fmt.Sprintf("📦 %s | Format: %s | Size: %s | Modified: %s",
m.message = fmt.Sprintf("[PKG] %s | Format: %s | Size: %s | Modified: %s",
selected.Name,
selected.Format.String(),
formatSize(selected.Size),
@@ -251,13 +251,13 @@ func (m ArchiveBrowserModel) View() string {
var s strings.Builder
// Header
title := "📦 Backup Archives"
title := "[PKG] Backup Archives"
if m.mode == "restore-single" {
title = "📦 Select Archive to Restore (Single Database)"
title = "[PKG] Select Archive to Restore (Single Database)"
} else if m.mode == "restore-cluster" {
title = "📦 Select Archive to Restore (Cluster)"
title = "[PKG] Select Archive to Restore (Cluster)"
} else if m.mode == "diagnose" {
title = "🔍 Select Archive to Diagnose"
title = "[SEARCH] Select Archive to Diagnose"
}
s.WriteString(titleStyle.Render(title))
@@ -269,7 +269,7 @@ func (m ArchiveBrowserModel) View() string {
}
if m.err != nil {
s.WriteString(errorStyle.Render(fmt.Sprintf(" Error: %v", m.err)))
s.WriteString(errorStyle.Render(fmt.Sprintf("[FAIL] Error: %v", m.err)))
s.WriteString("\n\n")
s.WriteString(infoStyle.Render("Press Esc to go back"))
return s.String()
@@ -293,7 +293,7 @@ func (m ArchiveBrowserModel) View() string {
s.WriteString(archiveHeaderStyle.Render(fmt.Sprintf("%-40s %-25s %-12s %-20s",
"FILENAME", "FORMAT", "SIZE", "MODIFIED")))
s.WriteString("\n")
s.WriteString(strings.Repeat("", 100))
s.WriteString(strings.Repeat("-", 100))
s.WriteString("\n")
// Show archives (limit to visible area)
@@ -317,13 +317,13 @@ func (m ArchiveBrowserModel) View() string {
}
// Color code based on validity and age
statusIcon := ""
statusIcon := "[+]"
if !archive.Valid {
statusIcon = ""
statusIcon = "[-]"
style = archiveInvalidStyle
} else if time.Since(archive.Modified) > 30*24*time.Hour {
style = archiveOldStyle
statusIcon = ""
statusIcon = "[WARN]"
}
filename := truncate(archive.Name, 38)
@@ -351,7 +351,7 @@ func (m ArchiveBrowserModel) View() string {
s.WriteString(infoStyle.Render(fmt.Sprintf("Total: %d archive(s) | Selected: %d/%d",
len(m.archives), m.cursor+1, len(m.archives))))
s.WriteString("\n")
s.WriteString(infoStyle.Render("⌨️ ↑/↓: Navigate | Enter: Select | d: Diagnose | f: Filter | i: Info | Esc: Back"))
s.WriteString(infoStyle.Render("[KEY] ↑/↓: Navigate | Enter: Select | d: Diagnose | f: Filter | i: Info | Esc: Back"))
return s.String()
}

View File

@@ -136,11 +136,11 @@ func executeBackupWithTUIProgress(parentCtx context.Context, cfg *config.Config,
var result string
switch backupType {
case "single":
result = fmt.Sprintf(" Single database backup of '%s' completed successfully in %v", dbName, elapsed)
result = fmt.Sprintf("[+] Single database backup of '%s' completed successfully in %v", dbName, elapsed)
case "sample":
result = fmt.Sprintf(" Sample backup of '%s' (ratio: %d) completed successfully in %v", dbName, ratio, elapsed)
result = fmt.Sprintf("[+] Sample backup of '%s' (ratio: %d) completed successfully in %v", dbName, ratio, elapsed)
case "cluster":
result = fmt.Sprintf(" Cluster backup completed successfully in %v", elapsed)
result = fmt.Sprintf("[+] Cluster backup completed successfully in %v", elapsed)
}
return backupCompleteMsg{
@@ -200,9 +200,9 @@ func (m BackupExecutionModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.err = msg.err
m.result = msg.result
if m.err == nil {
m.status = " Backup completed successfully!"
m.status = "[OK] Backup completed successfully!"
} else {
m.status = fmt.Sprintf(" Backup failed: %v", m.err)
m.status = fmt.Sprintf("[FAIL] Backup failed: %v", m.err)
}
// Auto-forward in debug/auto-confirm mode
if m.config.TUIAutoConfirm {
@@ -216,7 +216,7 @@ func (m BackupExecutionModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if !m.done && !m.cancelling {
// User requested cancellation - cancel the context
m.cancelling = true
m.status = "⏹️ Cancelling backup... (please wait)"
m.status = "[STOP] Cancelling backup... (please wait)"
if m.cancel != nil {
m.cancel()
}
@@ -240,7 +240,7 @@ func (m BackupExecutionModel) View() string {
// Clear screen with newlines and render header
s.WriteString("\n\n")
header := titleStyle.Render("🔄 Backup Execution")
header := titleStyle.Render("[EXEC] Backup Execution")
s.WriteString(header)
s.WriteString("\n\n")
@@ -261,13 +261,13 @@ func (m BackupExecutionModel) View() string {
s.WriteString(fmt.Sprintf(" %s %s\n", spinnerFrames[m.spinnerFrame], m.status))
} else {
s.WriteString(fmt.Sprintf(" %s %s\n", spinnerFrames[m.spinnerFrame], m.status))
s.WriteString("\n ⌨️ Press Ctrl+C or ESC to cancel\n")
s.WriteString("\n [KEY] Press Ctrl+C or ESC to cancel\n")
}
} else {
s.WriteString(fmt.Sprintf(" %s\n\n", m.status))
if m.err != nil {
s.WriteString(fmt.Sprintf(" Error: %v\n", m.err))
s.WriteString(fmt.Sprintf(" [FAIL] Error: %v\n", m.err))
} else if m.result != "" {
// Parse and display result cleanly
lines := strings.Split(m.result, "\n")
@@ -278,7 +278,7 @@ func (m BackupExecutionModel) View() string {
}
}
}
s.WriteString("\n ⌨️ Press Enter or ESC to return to menu\n")
s.WriteString("\n [KEY] Press Enter or ESC to return to menu\n")
}
return s.String()

View File

@@ -86,7 +86,7 @@ func (m BackupManagerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Verify archive
if len(m.archives) > 0 && m.cursor < len(m.archives) {
selected := m.archives[m.cursor]
m.message = fmt.Sprintf("🔍 Verifying %s...", selected.Name)
m.message = fmt.Sprintf("[SEARCH] Verifying %s...", selected.Name)
// In real implementation, would run verification
}
@@ -96,16 +96,16 @@ func (m BackupManagerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
selected := m.archives[m.cursor]
archivePath := selected.Path
confirm := NewConfirmationModelWithAction(m.config, m.logger, m,
"🗑️ Delete Archive",
"[DELETE] Delete Archive",
fmt.Sprintf("Delete archive '%s'? This cannot be undone.", selected.Name),
func() (tea.Model, tea.Cmd) {
// Delete the archive
err := deleteArchive(archivePath)
if err != nil {
m.err = fmt.Errorf("failed to delete archive: %v", err)
m.message = fmt.Sprintf(" Failed to delete: %v", err)
m.message = fmt.Sprintf("[FAIL] Failed to delete: %v", err)
} else {
m.message = fmt.Sprintf(" Deleted: %s", selected.Name)
m.message = fmt.Sprintf("[OK] Deleted: %s", selected.Name)
}
// Refresh the archive list
m.loading = true
@@ -118,7 +118,7 @@ func (m BackupManagerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Show info
if len(m.archives) > 0 && m.cursor < len(m.archives) {
selected := m.archives[m.cursor]
m.message = fmt.Sprintf("📦 %s | %s | %s | Modified: %s",
m.message = fmt.Sprintf("[PKG] %s | %s | %s | Modified: %s",
selected.Name,
selected.Format.String(),
formatSize(selected.Size),
@@ -152,7 +152,7 @@ func (m BackupManagerModel) View() string {
var s strings.Builder
// Title
s.WriteString(titleStyle.Render("🗄️ Backup Archive Manager"))
s.WriteString(titleStyle.Render("[DB] Backup Archive Manager"))
s.WriteString("\n\n")
if m.loading {
@@ -161,7 +161,7 @@ func (m BackupManagerModel) View() string {
}
if m.err != nil {
s.WriteString(errorStyle.Render(fmt.Sprintf(" Error: %v", m.err)))
s.WriteString(errorStyle.Render(fmt.Sprintf("[FAIL] Error: %v", m.err)))
s.WriteString("\n\n")
s.WriteString(infoStyle.Render("Press Esc to go back"))
return s.String()
@@ -184,7 +184,7 @@ func (m BackupManagerModel) View() string {
s.WriteString(archiveHeaderStyle.Render(fmt.Sprintf("%-35s %-25s %-12s %-20s",
"FILENAME", "FORMAT", "SIZE", "MODIFIED")))
s.WriteString("\n")
s.WriteString(strings.Repeat("", 95))
s.WriteString(strings.Repeat("-", 95))
s.WriteString("\n")
// Show archives (limit to visible area)
@@ -208,12 +208,12 @@ func (m BackupManagerModel) View() string {
}
// Status icon
statusIcon := ""
statusIcon := "[+]"
if !archive.Valid {
statusIcon = ""
statusIcon = "[-]"
style = archiveInvalidStyle
} else if time.Since(archive.Modified) > 30*24*time.Hour {
statusIcon = ""
statusIcon = "[WARN]"
}
filename := truncate(archive.Name, 33)
@@ -240,7 +240,7 @@ func (m BackupManagerModel) View() string {
s.WriteString(infoStyle.Render(fmt.Sprintf("Selected: %d/%d", m.cursor+1, len(m.archives))))
s.WriteString("\n")
s.WriteString(infoStyle.Render("⌨️ ↑/↓: Navigate | r: Restore | v: Verify | d: Delete | i: Info | R: Refresh | Esc: Back"))
s.WriteString(infoStyle.Render("[KEY] ↑/↓: Navigate | r: Restore | v: Verify | d: Delete | i: Info | R: Refresh | Esc: Back"))
return s.String()
}

View File

@@ -129,7 +129,7 @@ func (m ConfirmationModel) View() string {
s.WriteString(" ")
}
s.WriteString("\n\n⌨️ ←/→: Select Enter/y: Confirm n/ESC: Cancel\n")
s.WriteString("\n\n[KEYS] <-/->: Select | Enter/y: Confirm | n/ESC: Cancel\n")
return s.String()
}

View File

@@ -109,7 +109,7 @@ func (m DatabaseSelectorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return executor, executor.Init()
}
inputModel := NewInputModel(m.config, m.logger, m,
"📊 Sample Ratio",
"[STATS] Sample Ratio",
"Enter sample ratio (1-100):",
"10",
ValidateInt(1, 100))
@@ -152,7 +152,7 @@ func (m DatabaseSelectorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// If sample backup, ask for ratio first
if m.backupType == "sample" {
inputModel := NewInputModel(m.config, m.logger, m,
"📊 Sample Ratio",
"[STATS] Sample Ratio",
"Enter sample ratio (1-100):",
"10",
ValidateInt(1, 100))
@@ -176,12 +176,12 @@ func (m DatabaseSelectorModel) View() string {
s.WriteString(fmt.Sprintf("\n%s\n\n", header))
if m.loading {
s.WriteString(" Loading databases...\n")
s.WriteString("[WAIT] Loading databases...\n")
return s.String()
}
if m.err != nil {
s.WriteString(fmt.Sprintf(" Error: %v\n", m.err))
s.WriteString(fmt.Sprintf("[FAIL] Error: %v\n", m.err))
s.WriteString("\nPress ESC to go back\n")
return s.String()
}
@@ -203,7 +203,7 @@ func (m DatabaseSelectorModel) View() string {
s.WriteString(fmt.Sprintf("\n%s\n", m.message))
}
s.WriteString("\n⌨️ ↑/↓: Navigate Enter: Select ESC: Back q: Quit\n")
s.WriteString("\n[KEYS] Up/Down: Navigate | Enter: Select | ESC: Back | q: Quit\n")
return s.String()
}

View File

@@ -160,7 +160,7 @@ func (m DiagnoseViewModel) View() string {
var s strings.Builder
// Header
s.WriteString(titleStyle.Render("🔍 Backup Diagnosis"))
s.WriteString(titleStyle.Render("[SEARCH] Backup Diagnosis"))
s.WriteString("\n\n")
// Archive info
@@ -175,14 +175,14 @@ func (m DiagnoseViewModel) View() string {
s.WriteString("\n\n")
if m.running {
s.WriteString(infoStyle.Render(" " + m.progress))
s.WriteString(infoStyle.Render("[WAIT] " + m.progress))
s.WriteString("\n\n")
s.WriteString(diagnoseInfoStyle.Render("This may take a while for large archives..."))
return s.String()
}
if m.err != nil {
s.WriteString(errorStyle.Render(fmt.Sprintf(" Diagnosis failed: %v", m.err)))
s.WriteString(errorStyle.Render(fmt.Sprintf("[FAIL] Diagnosis failed: %v", m.err)))
s.WriteString("\n\n")
s.WriteString(infoStyle.Render("Press Enter or Esc to go back"))
return s.String()
@@ -205,72 +205,72 @@ func (m DiagnoseViewModel) renderSingleResult(result *restore.DiagnoseResult) st
var s strings.Builder
// Status
s.WriteString(strings.Repeat("", 60))
s.WriteString(strings.Repeat("-", 60))
s.WriteString("\n")
if result.IsValid {
s.WriteString(diagnosePassStyle.Render(" STATUS: VALID"))
s.WriteString(diagnosePassStyle.Render("[OK] STATUS: VALID"))
} else {
s.WriteString(diagnoseFailStyle.Render(" STATUS: INVALID"))
s.WriteString(diagnoseFailStyle.Render("[FAIL] STATUS: INVALID"))
}
s.WriteString("\n")
if result.IsTruncated {
s.WriteString(diagnoseFailStyle.Render("⚠️ TRUNCATED: File appears incomplete"))
s.WriteString(diagnoseFailStyle.Render("[WARN] TRUNCATED: File appears incomplete"))
s.WriteString("\n")
}
if result.IsCorrupted {
s.WriteString(diagnoseFailStyle.Render("⚠️ CORRUPTED: File structure is damaged"))
s.WriteString(diagnoseFailStyle.Render("[WARN] CORRUPTED: File structure is damaged"))
s.WriteString("\n")
}
s.WriteString(strings.Repeat("", 60))
s.WriteString(strings.Repeat("-", 60))
s.WriteString("\n\n")
// Details
if result.Details != nil {
s.WriteString(diagnoseHeaderStyle.Render("📊 DETAILS:"))
s.WriteString(diagnoseHeaderStyle.Render("[STATS] DETAILS:"))
s.WriteString("\n")
if result.Details.HasPGDMPSignature {
s.WriteString(diagnosePassStyle.Render(" "))
s.WriteString(diagnosePassStyle.Render(" [+] "))
s.WriteString("Has PGDMP signature (custom format)\n")
}
if result.Details.HasSQLHeader {
s.WriteString(diagnosePassStyle.Render(" "))
s.WriteString(diagnosePassStyle.Render(" [+] "))
s.WriteString("Has PostgreSQL SQL header\n")
}
if result.Details.GzipValid {
s.WriteString(diagnosePassStyle.Render(" "))
s.WriteString(diagnosePassStyle.Render(" [+] "))
s.WriteString("Gzip compression valid\n")
}
if result.Details.PgRestoreListable {
s.WriteString(diagnosePassStyle.Render(" "))
s.WriteString(diagnosePassStyle.Render(" [+] "))
s.WriteString(fmt.Sprintf("pg_restore can list contents (%d tables)\n", result.Details.TableCount))
}
if result.Details.CopyBlockCount > 0 {
s.WriteString(diagnoseInfoStyle.Render(" "))
s.WriteString(diagnoseInfoStyle.Render(" - "))
s.WriteString(fmt.Sprintf("Contains %d COPY blocks\n", result.Details.CopyBlockCount))
}
if result.Details.UnterminatedCopy {
s.WriteString(diagnoseFailStyle.Render(" "))
s.WriteString(diagnoseFailStyle.Render(" [-] "))
s.WriteString(fmt.Sprintf("Unterminated COPY block: %s (line %d)\n",
result.Details.LastCopyTable, result.Details.LastCopyLineNumber))
}
if result.Details.ProperlyTerminated {
s.WriteString(diagnosePassStyle.Render(" "))
s.WriteString(diagnosePassStyle.Render(" [+] "))
s.WriteString("All COPY blocks properly terminated\n")
}
if result.Details.ExpandedSize > 0 {
s.WriteString(diagnoseInfoStyle.Render(" "))
s.WriteString(diagnoseInfoStyle.Render(" - "))
s.WriteString(fmt.Sprintf("Expanded size: %s (ratio: %.1fx)\n",
formatSize(result.Details.ExpandedSize), result.Details.CompressionRatio))
}
@@ -279,14 +279,14 @@ func (m DiagnoseViewModel) renderSingleResult(result *restore.DiagnoseResult) st
// Errors
if len(result.Errors) > 0 {
s.WriteString("\n")
s.WriteString(diagnoseFailStyle.Render(" ERRORS:"))
s.WriteString(diagnoseFailStyle.Render("[FAIL] ERRORS:"))
s.WriteString("\n")
for i, e := range result.Errors {
if i >= 5 {
s.WriteString(diagnoseInfoStyle.Render(fmt.Sprintf(" ... and %d more\n", len(result.Errors)-5)))
break
}
s.WriteString(diagnoseFailStyle.Render(" "))
s.WriteString(diagnoseFailStyle.Render(" - "))
s.WriteString(truncate(e, 70))
s.WriteString("\n")
}
@@ -295,14 +295,14 @@ func (m DiagnoseViewModel) renderSingleResult(result *restore.DiagnoseResult) st
// Warnings
if len(result.Warnings) > 0 {
s.WriteString("\n")
s.WriteString(diagnoseWarnStyle.Render("⚠️ WARNINGS:"))
s.WriteString(diagnoseWarnStyle.Render("[WARN] WARNINGS:"))
s.WriteString("\n")
for i, w := range result.Warnings {
if i >= 3 {
s.WriteString(diagnoseInfoStyle.Render(fmt.Sprintf(" ... and %d more\n", len(result.Warnings)-3)))
break
}
s.WriteString(diagnoseWarnStyle.Render(" "))
s.WriteString(diagnoseWarnStyle.Render(" - "))
s.WriteString(truncate(w, 70))
s.WriteString("\n")
}
@@ -311,7 +311,7 @@ func (m DiagnoseViewModel) renderSingleResult(result *restore.DiagnoseResult) st
// Recommendations
if !result.IsValid {
s.WriteString("\n")
s.WriteString(diagnoseHeaderStyle.Render("💡 RECOMMENDATIONS:"))
s.WriteString(diagnoseHeaderStyle.Render("[HINT] RECOMMENDATIONS:"))
s.WriteString("\n")
if result.IsTruncated {
s.WriteString(" 1. Re-run the backup process for this database\n")
@@ -341,17 +341,17 @@ func (m DiagnoseViewModel) renderClusterResults() string {
}
}
s.WriteString(strings.Repeat("", 60))
s.WriteString(strings.Repeat("-", 60))
s.WriteString("\n")
s.WriteString(diagnoseHeaderStyle.Render(fmt.Sprintf("📊 CLUSTER SUMMARY: %d databases\n", len(m.results))))
s.WriteString(strings.Repeat("", 60))
s.WriteString(diagnoseHeaderStyle.Render(fmt.Sprintf("[STATS] CLUSTER SUMMARY: %d databases\n", len(m.results))))
s.WriteString(strings.Repeat("-", 60))
s.WriteString("\n\n")
if invalidCount == 0 {
s.WriteString(diagnosePassStyle.Render(" All dumps are valid"))
s.WriteString(diagnosePassStyle.Render("[OK] All dumps are valid"))
s.WriteString("\n\n")
} else {
s.WriteString(diagnoseFailStyle.Render(fmt.Sprintf(" %d/%d dumps have issues", invalidCount, len(m.results))))
s.WriteString(diagnoseFailStyle.Render(fmt.Sprintf("[FAIL] %d/%d dumps have issues", invalidCount, len(m.results))))
s.WriteString("\n\n")
}
@@ -378,13 +378,13 @@ func (m DiagnoseViewModel) renderClusterResults() string {
var status string
if r.IsValid {
status = diagnosePassStyle.Render("")
status = diagnosePassStyle.Render("[+]")
} else if r.IsTruncated {
status = diagnoseFailStyle.Render(" TRUNCATED")
status = diagnoseFailStyle.Render("[-] TRUNCATED")
} else if r.IsCorrupted {
status = diagnoseFailStyle.Render(" CORRUPTED")
status = diagnoseFailStyle.Render("[-] CORRUPTED")
} else {
status = diagnoseFailStyle.Render(" INVALID")
status = diagnoseFailStyle.Render("[-] INVALID")
}
line := fmt.Sprintf("%s %s %-35s %s",
@@ -405,7 +405,7 @@ func (m DiagnoseViewModel) renderClusterResults() string {
if m.cursor < len(m.results) {
selected := m.results[m.cursor]
s.WriteString("\n")
s.WriteString(strings.Repeat("", 60))
s.WriteString(strings.Repeat("-", 60))
s.WriteString("\n")
s.WriteString(diagnoseHeaderStyle.Render("Selected: " + selected.FileName))
s.WriteString("\n\n")
@@ -413,7 +413,7 @@ func (m DiagnoseViewModel) renderClusterResults() string {
// Show condensed details for selected
if selected.Details != nil {
if selected.Details.UnterminatedCopy {
s.WriteString(diagnoseFailStyle.Render(" Unterminated COPY: "))
s.WriteString(diagnoseFailStyle.Render(" [-] Unterminated COPY: "))
s.WriteString(selected.Details.LastCopyTable)
s.WriteString(fmt.Sprintf(" (line %d)\n", selected.Details.LastCopyLineNumber))
}
@@ -429,7 +429,7 @@ func (m DiagnoseViewModel) renderClusterResults() string {
if i >= 2 {
break
}
s.WriteString(diagnoseFailStyle.Render(" "))
s.WriteString(diagnoseFailStyle.Render(" - "))
s.WriteString(truncate(e, 55))
s.WriteString("\n")
}

View File

@@ -208,7 +208,7 @@ func (dp *DirectoryPicker) View() string {
if dp.allowFiles {
pickerType = "File/Directory"
}
header := fmt.Sprintf("📁 %s Picker - %s", pickerType, dp.currentPath)
header := fmt.Sprintf("[DIR] %s Picker - %s", pickerType, dp.currentPath)
content.WriteString(dp.styles.Header.Render(header))
content.WriteString("\n\n")
@@ -216,13 +216,13 @@ func (dp *DirectoryPicker) View() string {
for i, item := range dp.items {
var prefix string
if item.Name == ".." {
prefix = "⬆️ "
prefix = "[UP] "
} else if item.Name == "Error reading directory" {
prefix = " "
prefix = "[X] "
} else if item.IsDir {
prefix = "📁 "
prefix = "[DIR] "
} else {
prefix = "📄 "
prefix = "[FILE] "
}
line := prefix + item.Name
@@ -235,9 +235,9 @@ func (dp *DirectoryPicker) View() string {
}
// Help text
help := "\n↑/↓: Navigate Enter: Open/Select File s: Select Directory q/Esc: Cancel"
help := "\nUp/Down: Navigate | Enter: Open/Select File | s: Select Directory | q/Esc: Cancel"
if !dp.allowFiles {
help = "\n↑/↓: Navigate Enter: Open s: Select Directory q/Esc: Cancel"
help = "\nUp/Down: Navigate | Enter: Open | s: Select Directory | q/Esc: Cancel"
}
content.WriteString(dp.styles.Help.Render(help))

View File

@@ -104,7 +104,7 @@ func loadHistory(cfg *config.Config) []HistoryEntry {
Type: backupType,
Database: database,
Timestamp: info.ModTime(),
Status: " Completed",
Status: "[OK] Completed",
Filename: name,
})
}
@@ -191,11 +191,11 @@ func (m HistoryViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m HistoryViewModel) View() string {
var s strings.Builder
header := titleStyle.Render("📜 Operation History")
header := titleStyle.Render("[HISTORY] Operation History")
s.WriteString(fmt.Sprintf("\n%s\n\n", header))
if len(m.history) == 0 {
s.WriteString("📭 No backup history found\n\n")
s.WriteString("[EMPTY] No backup history found\n\n")
} else {
maxVisible := 15 // Show max 15 items at once
@@ -211,7 +211,7 @@ func (m HistoryViewModel) View() string {
// Show scroll indicators
if start > 0 {
s.WriteString(" More entries above...\n")
s.WriteString(" [^] More entries above...\n")
}
// Display only visible entries
@@ -233,13 +233,13 @@ func (m HistoryViewModel) View() string {
// Show scroll indicator if more entries below
if end < len(m.history) {
s.WriteString(fmt.Sprintf(" %d more entries below...\n", len(m.history)-end))
s.WriteString(fmt.Sprintf(" [v] %d more entries below...\n", len(m.history)-end))
}
s.WriteString("\n")
}
s.WriteString("⌨️ ↑/↓: Navigate PgUp/PgDn: Jump Home/End: First/Last ESC: Back q: Quit\n")
s.WriteString("[KEYS] Up/Down: Navigate - PgUp/PgDn: Jump - Home/End: First/Last - ESC: Back - q: Quit\n")
return s.String()
}

View File

@@ -137,10 +137,10 @@ func (m InputModel) View() string {
s.WriteString("\n\n")
if m.err != nil {
s.WriteString(errorStyle.Render(fmt.Sprintf(" Error: %v\n\n", m.err)))
s.WriteString(errorStyle.Render(fmt.Sprintf("[FAIL] Error: %v\n\n", m.err)))
}
s.WriteString("⌨️ Type value Enter: Confirm ESC: Cancel\n")
s.WriteString("[KEYS] Type value | Enter: Confirm | ESC: Cancel\n")
return s.String()
}

View File

@@ -89,12 +89,12 @@ func NewMenuModel(cfg *config.Config, log logger.Logger) *MenuModel {
"Single Database Backup",
"Sample Database Backup (with ratio)",
"Cluster Backup (all databases)",
"────────────────────────────────",
"--------------------------------",
"Restore Single Database",
"Restore Cluster Backup",
"Diagnose Backup File",
"List & Manage Backups",
"────────────────────────────────",
"--------------------------------",
"View Active Operations",
"Show Operation History",
"Database Status & Health Check",
@@ -177,7 +177,7 @@ func (m *MenuModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case 12: // Settings
return m.handleSettings()
case 13: // Clear History
m.message = "🗑️ History cleared"
m.message = "[DEL] History cleared"
case 14: // Quit
if m.cancel != nil {
m.cancel()
@@ -262,7 +262,7 @@ func (m *MenuModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case 12: // Settings
return m.handleSettings()
case 13: // Clear History
m.message = "🗑️ History cleared"
m.message = "[DEL] History cleared"
case 14: // Quit
if m.cancel != nil {
m.cancel()
@@ -285,7 +285,7 @@ func (m *MenuModel) View() string {
var s string
// Header
header := titleStyle.Render("🗄️ Database Backup Tool - Interactive Menu")
header := titleStyle.Render("[DB] Database Backup Tool - Interactive Menu")
s += fmt.Sprintf("\n%s\n\n", header)
if len(m.dbTypes) > 0 {
@@ -299,7 +299,7 @@ func (m *MenuModel) View() string {
}
selector := fmt.Sprintf("Target Engine: %s", strings.Join(options, menuStyle.Render(" | ")))
s += dbSelectorLabelStyle.Render(selector) + "\n"
hint := infoStyle.Render("Switch with ←/→ or t Cluster backup requires PostgreSQL")
hint := infoStyle.Render("Switch with <-/-> or t | Cluster backup requires PostgreSQL")
s += hint + "\n"
}
@@ -326,7 +326,7 @@ func (m *MenuModel) View() string {
}
// Footer
footer := infoStyle.Render("\n⌨️ Press ↑/↓ to navigate Enter to select q to quit")
footer := infoStyle.Render("\n[KEYS] Press Up/Down to navigate | Enter to select | q to quit")
s += footer
return s
@@ -334,20 +334,20 @@ func (m *MenuModel) View() string {
// handleSingleBackup opens database selector for single backup
func (m *MenuModel) handleSingleBackup() (tea.Model, tea.Cmd) {
selector := NewDatabaseSelector(m.config, m.logger, m, m.ctx, "🗄️ Single Database Backup", "single")
selector := NewDatabaseSelector(m.config, m.logger, m, m.ctx, "[DB] Single Database Backup", "single")
return selector, selector.Init()
}
// handleSampleBackup opens database selector for sample backup
func (m *MenuModel) handleSampleBackup() (tea.Model, tea.Cmd) {
selector := NewDatabaseSelector(m.config, m.logger, m, m.ctx, "📊 Sample Database Backup", "sample")
selector := NewDatabaseSelector(m.config, m.logger, m, m.ctx, "[STATS] Sample Database Backup", "sample")
return selector, selector.Init()
}
// handleClusterBackup shows confirmation and executes cluster backup
func (m *MenuModel) handleClusterBackup() (tea.Model, tea.Cmd) {
if !m.config.IsPostgreSQL() {
m.message = errorStyle.Render(" Cluster backup is available only for PostgreSQL targets")
m.message = errorStyle.Render("[FAIL] Cluster backup is available only for PostgreSQL targets")
return m, nil
}
// Skip confirmation in auto-confirm mode
@@ -356,7 +356,7 @@ func (m *MenuModel) handleClusterBackup() (tea.Model, tea.Cmd) {
return executor, executor.Init()
}
confirm := NewConfirmationModelWithAction(m.config, m.logger, m,
"🗄️ Cluster Backup",
"[DB] Cluster Backup",
"This will backup ALL databases in the cluster. Continue?",
func() (tea.Model, tea.Cmd) {
executor := NewBackupExecution(m.config, m.logger, m, m.ctx, "cluster", "", 0)
@@ -399,7 +399,7 @@ func (m *MenuModel) handleRestoreSingle() (tea.Model, tea.Cmd) {
// handleRestoreCluster opens archive browser for cluster restore
func (m *MenuModel) handleRestoreCluster() (tea.Model, tea.Cmd) {
if !m.config.IsPostgreSQL() {
m.message = errorStyle.Render(" Cluster restore is available only for PostgreSQL")
m.message = errorStyle.Render("[FAIL] Cluster restore is available only for PostgreSQL")
return m, nil
}
browser := NewArchiveBrowser(m.config, m.logger, m, m.ctx, "restore-cluster")
@@ -428,7 +428,7 @@ func (m *MenuModel) applyDatabaseSelection() {
selection := m.dbTypes[m.dbTypeCursor]
if err := m.config.SetDatabaseType(selection.value); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" %v", err))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] %v", err))
return
}
@@ -437,7 +437,7 @@ func (m *MenuModel) applyDatabaseSelection() {
m.config.Port = m.config.GetDefaultPort()
}
m.message = successStyle.Render(fmt.Sprintf("🔀 Target database set to %s", m.config.DisplayDatabaseType()))
m.message = successStyle.Render(fmt.Sprintf("[SWITCH] Target database set to %s", m.config.DisplayDatabaseType()))
if m.logger != nil {
m.logger.Info("updated target database type", "type", m.config.DatabaseType, "port", m.config.Port)
}

View File

@@ -49,14 +49,14 @@ func (m OperationsViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m OperationsViewModel) View() string {
var s strings.Builder
header := titleStyle.Render("📊 Active Operations")
header := titleStyle.Render("[STATS] Active Operations")
s.WriteString(fmt.Sprintf("\n%s\n\n", header))
s.WriteString("Currently running operations:\n\n")
s.WriteString(infoStyle.Render("📭 No active operations"))
s.WriteString(infoStyle.Render("[NONE] No active operations"))
s.WriteString("\n\n")
s.WriteString("⌨️ Press any key to return to menu\n")
s.WriteString("[KEYS] Press any key to return to menu\n")
return s.String()
}

View File

@@ -285,7 +285,7 @@ func (m RestoreExecutionModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if !m.done && !m.cancelling {
// User requested cancellation - cancel the context
m.cancelling = true
m.status = "⏹️ Cancelling restore... (please wait)"
m.status = "[STOP] Cancelling restore... (please wait)"
m.phase = "Cancelling"
if m.cancel != nil {
m.cancel()
@@ -297,7 +297,7 @@ func (m RestoreExecutionModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "q":
if !m.done && !m.cancelling {
m.cancelling = true
m.status = "⏹️ Cancelling restore... (please wait)"
m.status = "[STOP] Cancelling restore... (please wait)"
m.phase = "Cancelling"
if m.cancel != nil {
m.cancel()
@@ -321,9 +321,9 @@ func (m RestoreExecutionModel) View() string {
s.Grow(512) // Pre-allocate estimated capacity for better performance
// Title
title := "💾 Restoring Database"
title := "[RESTORE] Restoring Database"
if m.restoreType == "restore-cluster" {
title = "💾 Restoring Cluster"
title = "[RESTORE] Restoring Cluster"
}
s.WriteString(titleStyle.Render(title))
s.WriteString("\n\n")
@@ -338,12 +338,12 @@ func (m RestoreExecutionModel) View() string {
if m.done {
// Show result
if m.err != nil {
s.WriteString(errorStyle.Render(" Restore Failed"))
s.WriteString(errorStyle.Render("[FAIL] Restore Failed"))
s.WriteString("\n\n")
s.WriteString(errorStyle.Render(fmt.Sprintf("Error: %v", m.err)))
s.WriteString("\n")
} else {
s.WriteString(successStyle.Render(" Restore Completed Successfully"))
s.WriteString(successStyle.Render("[OK] Restore Completed Successfully"))
s.WriteString("\n\n")
s.WriteString(successStyle.Render(m.result))
s.WriteString("\n")
@@ -351,7 +351,7 @@ func (m RestoreExecutionModel) View() string {
s.WriteString(fmt.Sprintf("\nElapsed Time: %s\n", formatDuration(m.elapsed)))
s.WriteString("\n")
s.WriteString(infoStyle.Render("⌨️ Press Enter to continue"))
s.WriteString(infoStyle.Render("[KEYS] Press Enter to continue"))
} else {
// Show progress
s.WriteString(fmt.Sprintf("Phase: %s\n", m.phase))
@@ -373,7 +373,7 @@ func (m RestoreExecutionModel) View() string {
// Elapsed time
s.WriteString(fmt.Sprintf("Elapsed: %s\n", formatDuration(m.elapsed)))
s.WriteString("\n")
s.WriteString(infoStyle.Render("⌨️ Press Ctrl+C to cancel"))
s.WriteString(infoStyle.Render("[KEYS] Press Ctrl+C to cancel"))
}
return s.String()

View File

@@ -264,7 +264,7 @@ func (m RestorePreviewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Toggle cluster cleanup
m.cleanClusterFirst = !m.cleanClusterFirst
if m.cleanClusterFirst {
m.message = checkWarningStyle.Render(fmt.Sprintf("⚠️ Will drop %d existing database(s) before restore", m.existingDBCount))
m.message = checkWarningStyle.Render(fmt.Sprintf("[WARN] Will drop %d existing database(s) before restore", m.existingDBCount))
} else {
m.message = fmt.Sprintf("Clean cluster first: disabled")
}
@@ -278,7 +278,7 @@ func (m RestorePreviewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Toggle debug log saving
m.saveDebugLog = !m.saveDebugLog
if m.saveDebugLog {
m.message = infoStyle.Render("📋 Debug log: enabled (will save detailed report on failure)")
m.message = infoStyle.Render("[DEBUG] Debug log: enabled (will save detailed report on failure)")
} else {
m.message = "Debug log: disabled"
}
@@ -288,7 +288,7 @@ func (m RestorePreviewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.workDir == "" {
// Set to backup directory as default alternative
m.workDir = m.config.BackupDir
m.message = infoStyle.Render(fmt.Sprintf("📁 Work directory set to: %s", m.workDir))
m.message = infoStyle.Render(fmt.Sprintf("[DIR] Work directory set to: %s", m.workDir))
} else {
// Clear work directory (use system temp)
m.workDir = ""
@@ -302,7 +302,7 @@ func (m RestorePreviewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
if !m.canProceed {
m.message = errorStyle.Render(" Cannot proceed - critical safety checks failed")
m.message = errorStyle.Render("[FAIL] Cannot proceed - critical safety checks failed")
return m, nil
}
@@ -319,15 +319,15 @@ func (m RestorePreviewModel) View() string {
var s strings.Builder
// Title
title := "🔍 Restore Preview"
title := "Restore Preview"
if m.mode == "restore-cluster" {
title = "🔍 Cluster Restore Preview"
title = "Cluster Restore Preview"
}
s.WriteString(titleStyle.Render(title))
s.WriteString("\n\n")
// Archive Information
s.WriteString(archiveHeaderStyle.Render("📦 Archive Information"))
s.WriteString(archiveHeaderStyle.Render("[ARCHIVE] Information"))
s.WriteString("\n")
s.WriteString(fmt.Sprintf(" File: %s\n", m.archive.Name))
s.WriteString(fmt.Sprintf(" Format: %s\n", m.archive.Format.String()))
@@ -340,25 +340,25 @@ func (m RestorePreviewModel) View() string {
// Target Information
if m.mode == "restore-single" {
s.WriteString(archiveHeaderStyle.Render("🎯 Target Information"))
s.WriteString(archiveHeaderStyle.Render("[TARGET] Information"))
s.WriteString("\n")
s.WriteString(fmt.Sprintf(" Database: %s\n", m.targetDB))
s.WriteString(fmt.Sprintf(" Host: %s:%d\n", m.config.Host, m.config.Port))
cleanIcon := ""
cleanIcon := "[N]"
if m.cleanFirst {
cleanIcon = ""
cleanIcon = "[Y]"
}
s.WriteString(fmt.Sprintf(" Clean First: %s %v\n", cleanIcon, m.cleanFirst))
createIcon := ""
createIcon := "[N]"
if m.createIfMissing {
createIcon = ""
createIcon = "[Y]"
}
s.WriteString(fmt.Sprintf(" Create If Missing: %s %v\n", createIcon, m.createIfMissing))
s.WriteString("\n")
} else if m.mode == "restore-cluster" {
s.WriteString(archiveHeaderStyle.Render("🎯 Cluster Restore Options"))
s.WriteString(archiveHeaderStyle.Render("[CLUSTER] Restore Options"))
s.WriteString("\n")
s.WriteString(fmt.Sprintf(" Host: %s:%d\n", m.config.Host, m.config.Port))
@@ -376,10 +376,10 @@ func (m RestorePreviewModel) View() string {
s.WriteString(fmt.Sprintf(" - %s\n", db))
}
cleanIcon := ""
cleanIcon := "[N]"
cleanStyle := infoStyle
if m.cleanClusterFirst {
cleanIcon = ""
cleanIcon = "[Y]"
cleanStyle = checkWarningStyle
}
s.WriteString(cleanStyle.Render(fmt.Sprintf(" Clean All First: %s %v (press 'c' to toggle)\n", cleanIcon, m.cleanClusterFirst)))
@@ -390,7 +390,7 @@ func (m RestorePreviewModel) View() string {
}
// Safety Checks
s.WriteString(archiveHeaderStyle.Render("🛡️ Safety Checks"))
s.WriteString(archiveHeaderStyle.Render("[SAFETY] Checks"))
s.WriteString("\n")
if m.checking {
@@ -398,21 +398,21 @@ func (m RestorePreviewModel) View() string {
s.WriteString("\n")
} else {
for _, check := range m.safetyChecks {
icon := ""
icon := "[ ]"
style := checkPendingStyle
switch check.Status {
case "passed":
icon = ""
icon = "[+]"
style = checkPassedStyle
case "failed":
icon = ""
icon = "[-]"
style = checkFailedStyle
case "warning":
icon = ""
icon = "[!]"
style = checkWarningStyle
case "checking":
icon = ""
icon = "[~]"
style = checkPendingStyle
}
@@ -428,13 +428,13 @@ func (m RestorePreviewModel) View() string {
// Warnings
if m.cleanFirst {
s.WriteString(checkWarningStyle.Render("⚠️ Warning: Clean-first enabled"))
s.WriteString(checkWarningStyle.Render("[WARN] Warning: Clean-first enabled"))
s.WriteString("\n")
s.WriteString(infoStyle.Render(" All existing data in target database will be dropped!"))
s.WriteString("\n\n")
}
if m.cleanClusterFirst && m.existingDBCount > 0 {
s.WriteString(checkWarningStyle.Render("🔥 WARNING: Cluster cleanup enabled"))
s.WriteString(checkWarningStyle.Render("[DANGER] WARNING: Cluster cleanup enabled"))
s.WriteString("\n")
s.WriteString(checkWarningStyle.Render(fmt.Sprintf(" %d existing database(s) will be DROPPED before restore!", m.existingDBCount)))
s.WriteString("\n")
@@ -443,30 +443,30 @@ func (m RestorePreviewModel) View() string {
}
// Advanced Options
s.WriteString(archiveHeaderStyle.Render("⚙️ Advanced Options"))
s.WriteString(archiveHeaderStyle.Render("[OPTIONS] Advanced"))
s.WriteString("\n")
// Work directory option
workDirIcon := ""
workDirIcon := "[-]"
workDirStyle := infoStyle
workDirValue := "(system temp)"
if m.workDir != "" {
workDirIcon = ""
workDirIcon = "[+]"
workDirStyle = checkPassedStyle
workDirValue = m.workDir
}
s.WriteString(workDirStyle.Render(fmt.Sprintf(" %s Work Dir: %s (press 'w' to toggle)", workDirIcon, workDirValue)))
s.WriteString("\n")
if m.workDir == "" {
s.WriteString(infoStyle.Render(" ⚠️ Large archives need more space than /tmp may have"))
s.WriteString(infoStyle.Render(" [WARN] Large archives need more space than /tmp may have"))
s.WriteString("\n")
}
// Debug log option
debugIcon := ""
debugIcon := "[-]"
debugStyle := infoStyle
if m.saveDebugLog {
debugIcon = ""
debugIcon = "[+]"
debugStyle = checkPassedStyle
}
s.WriteString(debugStyle.Render(fmt.Sprintf(" %s Debug Log: %v (press 'd' to toggle)", debugIcon, m.saveDebugLog)))
@@ -485,25 +485,25 @@ func (m RestorePreviewModel) View() string {
// Footer
if m.checking {
s.WriteString(infoStyle.Render("⌨️ Please wait..."))
s.WriteString(infoStyle.Render("Please wait..."))
} else if m.canProceed {
s.WriteString(successStyle.Render(" Ready to restore"))
s.WriteString(successStyle.Render("[OK] Ready to restore"))
s.WriteString("\n")
if m.mode == "restore-single" {
s.WriteString(infoStyle.Render("⌨️ t: Clean-first | c: Create | w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
s.WriteString(infoStyle.Render("t: Clean-first | c: Create | w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
} else if m.mode == "restore-cluster" {
if m.existingDBCount > 0 {
s.WriteString(infoStyle.Render("⌨️ c: Cleanup | w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
s.WriteString(infoStyle.Render("c: Cleanup | w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
} else {
s.WriteString(infoStyle.Render("⌨️ w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
s.WriteString(infoStyle.Render("w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
}
} else {
s.WriteString(infoStyle.Render("⌨️ w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
s.WriteString(infoStyle.Render("w: WorkDir | d: Debug | Enter: Proceed | Esc: Cancel"))
}
} else {
s.WriteString(errorStyle.Render(" Cannot proceed - please fix errors above"))
s.WriteString(errorStyle.Render("[FAIL] Cannot proceed - please fix errors above"))
s.WriteString("\n")
s.WriteString(infoStyle.Render("⌨️ Esc: Go back"))
s.WriteString(infoStyle.Render("Esc: Go back"))
}
return s.String()

View File

@@ -459,9 +459,9 @@ func (m SettingsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.cursor < len(m.settings) {
setting := m.settings[m.cursor]
if err := setting.Update(m.config, selectedPath); err != nil {
m.message = " Error: " + err.Error()
m.message = "[FAIL] Error: " + err.Error()
} else {
m.message = " Directory updated: " + selectedPath
m.message = "[OK] Directory updated: " + selectedPath
}
}
m.browsingDir = false
@@ -500,9 +500,9 @@ func (m SettingsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
currentSetting := m.settings[m.cursor]
if currentSetting.Type == "selector" {
if err := currentSetting.Update(m.config, ""); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" %s", err.Error()))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] %s", err.Error()))
} else {
m.message = successStyle.Render(fmt.Sprintf(" Updated %s", currentSetting.DisplayName))
m.message = successStyle.Render(fmt.Sprintf("[OK] Updated %s", currentSetting.DisplayName))
}
return m, nil
}
@@ -515,11 +515,11 @@ func (m SettingsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.settings[m.cursor].Type == "path" {
return m.openDirectoryBrowser()
} else {
m.message = " Tab key only works on directory path fields"
m.message = "[FAIL] Tab key only works on directory path fields"
return m, nil
}
} else {
m.message = " Invalid selection"
m.message = "[FAIL] Invalid selection"
return m, nil
}
@@ -597,18 +597,18 @@ func (m SettingsModel) saveEditedValue() (tea.Model, tea.Cmd) {
}
if setting == nil {
m.message = errorStyle.Render(" Setting not found")
m.message = errorStyle.Render("[FAIL] Setting not found")
m.editing = false
return m, nil
}
// Update the configuration
if err := setting.Update(m.config, m.editingValue); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" %s", err.Error()))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] %s", err.Error()))
return m, nil
}
m.message = successStyle.Render(fmt.Sprintf(" Updated %s", setting.DisplayName))
m.message = successStyle.Render(fmt.Sprintf("[OK] Updated %s", setting.DisplayName))
m.editing = false
m.editingField = ""
m.editingValue = ""
@@ -628,7 +628,7 @@ func (m SettingsModel) resetToDefaults() (tea.Model, tea.Cmd) {
newConfig.DatabaseType = m.config.DatabaseType
*m.config = *newConfig
m.message = successStyle.Render(" Settings reset to defaults")
m.message = successStyle.Render("[OK] Settings reset to defaults")
return m, nil
}
@@ -636,19 +636,19 @@ func (m SettingsModel) resetToDefaults() (tea.Model, tea.Cmd) {
// saveSettings validates and saves current settings
func (m SettingsModel) saveSettings() (tea.Model, tea.Cmd) {
if err := m.config.Validate(); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" Validation failed: %s", err.Error()))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] Validation failed: %s", err.Error()))
return m, nil
}
// Optimize CPU settings if auto-detect is enabled
if m.config.AutoDetectCores {
if err := m.config.OptimizeForCPU(); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" CPU optimization failed: %s", err.Error()))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] CPU optimization failed: %s", err.Error()))
return m, nil
}
}
m.message = successStyle.Render(" Settings validated and saved")
m.message = successStyle.Render("[OK] Settings validated and saved")
return m, nil
}
@@ -671,11 +671,11 @@ func (m SettingsModel) cycleDatabaseType() (tea.Model, tea.Cmd) {
// Update config
if err := m.config.SetDatabaseType(newType); err != nil {
m.message = errorStyle.Render(fmt.Sprintf(" Failed to set database type: %s", err.Error()))
m.message = errorStyle.Render(fmt.Sprintf("[FAIL] Failed to set database type: %s", err.Error()))
return m, nil
}
m.message = successStyle.Render(fmt.Sprintf(" Database type set to %s", m.config.DisplayDatabaseType()))
m.message = successStyle.Render(fmt.Sprintf("[OK] Database type set to %s", m.config.DisplayDatabaseType()))
return m, nil
}
@@ -688,7 +688,7 @@ func (m SettingsModel) View() string {
var b strings.Builder
// Header
header := titleStyle.Render("⚙️ Configuration Settings")
header := titleStyle.Render("[CFG] Configuration Settings")
b.WriteString(fmt.Sprintf("\n%s\n\n", header))
// Settings list
@@ -710,7 +710,7 @@ func (m SettingsModel) View() string {
}
line := fmt.Sprintf("%s %s: %s", cursor, setting.DisplayName, editValue)
b.WriteString(selectedStyle.Render(line))
b.WriteString(" ✏️")
b.WriteString(" [EDIT]")
} else {
line := fmt.Sprintf("%s %s: %s", cursor, setting.DisplayName, displayValue)
b.WriteString(selectedStyle.Render(line))
@@ -747,7 +747,7 @@ func (m SettingsModel) View() string {
// Current configuration summary
if !m.editing {
b.WriteString("\n")
b.WriteString(infoStyle.Render("📋 Current Configuration:"))
b.WriteString(infoStyle.Render("[LOG] Current Configuration:"))
b.WriteString("\n")
summary := []string{
@@ -775,16 +775,16 @@ func (m SettingsModel) View() string {
// Footer with instructions
var footer string
if m.editing {
footer = infoStyle.Render("\n⌨️ Type new value Enter to save Esc to cancel")
footer = infoStyle.Render("\n[KEYS] Type new value | Enter to save | Esc to cancel")
} else {
if m.browsingDir {
footer = infoStyle.Render("\n⌨️ ↑/↓ navigate directories Enter open Space select Tab/Esc back to settings")
footer = infoStyle.Render("\n[KEYS] Up/Down navigate directories | Enter open | Space select | Tab/Esc back to settings")
} else {
// Show different help based on current selection
if m.cursor >= 0 && m.cursor < len(m.settings) && m.settings[m.cursor].Type == "path" {
footer = infoStyle.Render("\n⌨️ ↑/↓ navigate Enter edit Tab browse directories 's' save 'r' reset 'q' menu")
footer = infoStyle.Render("\n[KEYS] Up/Down navigate | Enter edit | Tab browse directories | 's' save | 'r' reset | 'q' menu")
} else {
footer = infoStyle.Render("\n⌨️ ↑/↓ navigate Enter edit 's' save 'r' reset 'q' menu Tab=dirs on path fields only")
footer = infoStyle.Render("\n[KEYS] Up/Down navigate | Enter edit | 's' save | 'r' reset | 'q' menu | Tab=dirs on path fields only")
}
}
}

View File

@@ -160,25 +160,25 @@ func (m StatusViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m StatusViewModel) View() string {
var s strings.Builder
header := titleStyle.Render("📊 Database Status & Health Check")
header := titleStyle.Render("[STATS] Database Status & Health Check")
s.WriteString(fmt.Sprintf("\n%s\n\n", header))
if m.loading {
spinner := []string{"⠋", "⠙", "⠹", "", "", "⠴", "⠦", "⠧", "⠇", "⠏"}
spinner := []string{"-", "\\", "|", "/"}
frame := int(time.Now().UnixMilli()/100) % len(spinner)
s.WriteString(fmt.Sprintf("%s Loading status information...\n", spinner[frame]))
return s.String()
}
if m.err != nil {
s.WriteString(errorStyle.Render(fmt.Sprintf(" Error: %v\n", m.err)))
s.WriteString(errorStyle.Render(fmt.Sprintf("[FAIL] Error: %v\n", m.err)))
s.WriteString("\n")
} else {
s.WriteString("Connection Status:\n")
if m.connected {
s.WriteString(successStyle.Render(" Connected\n"))
s.WriteString(successStyle.Render(" [+] Connected\n"))
} else {
s.WriteString(errorStyle.Render(" Disconnected\n"))
s.WriteString(errorStyle.Render(" [-] Disconnected\n"))
}
s.WriteString("\n")
@@ -193,9 +193,9 @@ func (m StatusViewModel) View() string {
}
s.WriteString("\n")
s.WriteString(successStyle.Render(" All systems operational\n"))
s.WriteString(successStyle.Render("[+] All systems operational\n"))
}
s.WriteString("\n⌨️ Press any key to return to menu\n")
s.WriteString("\n[KEYS] Press any key to return to menu\n")
return s.String()
}