Tui 重构代码逻辑
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package wizard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
var split_line = splitlineStyle.Render(
|
||||
"───────────────────────────────────────────────────────────────")
|
||||
|
||||
// View 渲染视图
|
||||
func (m model) View() string {
|
||||
if m.done {
|
||||
@@ -19,38 +21,39 @@ func (m model) View() string {
|
||||
return errorView(m.err)
|
||||
}
|
||||
|
||||
var page string
|
||||
var pageContent string
|
||||
switch m.currentPage {
|
||||
case PageAgreement:
|
||||
page = m.agreementView()
|
||||
pageContent = renderLicensePage(m)
|
||||
case PageData:
|
||||
page = m.dataView()
|
||||
pageContent = renderDataInfoPage(m)
|
||||
case PagePublicNetwork:
|
||||
page = m.publicNetworkView()
|
||||
pageContent = renderPublicNetworkPage(m)
|
||||
case PageInternalNetwork:
|
||||
page = m.internalNetworkView()
|
||||
pageContent = renderInternalNetworkPage(m)
|
||||
case PageDNS:
|
||||
page = m.dnsView()
|
||||
pageContent = renderDNSPage(m)
|
||||
case PageSummary:
|
||||
page = m.summaryView()
|
||||
pageContent = renderSummaryPage(m)
|
||||
|
||||
default:
|
||||
pageContent = appStyle.Render("无效页面")
|
||||
}
|
||||
|
||||
content := strings.Builder{}
|
||||
content.WriteString(page)
|
||||
content.WriteString("\n\n")
|
||||
content.WriteString(progressView(m.currentPage, m.totalPages))
|
||||
|
||||
return containerStyle.Render(content.String())
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// agreementView 协议页面
|
||||
func (m model) agreementView() string {
|
||||
func makeRow(label, value string) string {
|
||||
return lipgloss.JoinHorizontal(lipgloss.Left,
|
||||
labelStyle.Render(label+":"),
|
||||
valueStyle.Render(value),
|
||||
)
|
||||
}
|
||||
|
||||
func renderLicensePage(m model) string {
|
||||
title := titleStyle.Render("SunHPC Software License Agreement")
|
||||
|
||||
agreement := agreementBox.Render(`
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ SunHPC License Agreement │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
licenseText := `
|
||||
───────────────────────────────────────────────────────────────
|
||||
1. License Grant
|
||||
This software grants you a non-exclusive, non-transferable
|
||||
license to use it.
|
||||
@@ -69,288 +72,265 @@ func (m model) agreementView() string {
|
||||
PLEASE READ THE ABOVE TERMS CAREFULLY AND CLICK "ACCEPT"
|
||||
TO AGREE AND FOLLOW THIS AGREEMENT.
|
||||
───────────────────────────────────────────────────────────────
|
||||
`)
|
||||
`
|
||||
|
||||
var acceptBtn, rejectBtn string
|
||||
if m.agreementIdx == 0 {
|
||||
rejectBtn = selectedButton.Render(">> Reject <<")
|
||||
acceptBtn = " Accept "
|
||||
} else {
|
||||
rejectBtn = " Reject "
|
||||
acceptBtn = selectedButton.Render(">> Accept <<")
|
||||
}
|
||||
|
||||
buttonGroup := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
acceptBtn, " ", rejectBtn)
|
||||
pageComps := m.pageComponents[PageAgreement]
|
||||
acceptBtn := pageComps["accept_btn"].View()
|
||||
rejectBtn := pageComps["reject_btn"].View()
|
||||
|
||||
// ✅ 添加调试信息(确认 agreementIdx 的值)
|
||||
// debugInfo := lipgloss.NewStyle().Foreground(lipgloss.Color("#888888")).
|
||||
// Render(fmt.Sprintf("[DEBUG: idx=%d]", m.agreementIdx),)
|
||||
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
pageContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
agreement, "",
|
||||
buttonGroup, "",
|
||||
// debugInfo, "", // ✅ 显示调试信息
|
||||
licenseTextStyle.Render(licenseText),
|
||||
lipgloss.JoinHorizontal(lipgloss.Center, acceptBtn, rejectBtn),
|
||||
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// dataView 数据接收页面
|
||||
func (m model) dataView() string {
|
||||
title := titleStyle.Render("Cluster Information")
|
||||
// ---------------- 页2:基础信息页渲染 ----------------
|
||||
func renderDataInfoPage(m model) string {
|
||||
pageComps := m.pageComponents[PageData]
|
||||
|
||||
var inputs strings.Builder
|
||||
for i, ti := range m.textInputs {
|
||||
info := fmt.Sprintf("%-10s|", m.inputLabels[i])
|
||||
input := inputBox.Render(info + ti.View())
|
||||
inputs.WriteString(input + "\n")
|
||||
}
|
||||
// 拼接基础信息表单
|
||||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
split_line,
|
||||
makeRow("Homepage", pageComps["Homepage_input"].View()),
|
||||
split_line,
|
||||
makeRow("Hostname", pageComps["Hostname_input"].View()),
|
||||
split_line,
|
||||
makeRow("Country", pageComps["Country_input"].View()),
|
||||
split_line,
|
||||
makeRow("Region", pageComps["Region_input"].View()),
|
||||
split_line,
|
||||
makeRow("Timezone", pageComps["Timezone_input"].View()),
|
||||
split_line,
|
||||
makeRow("DBPath", pageComps["DBPath_input"].View()),
|
||||
split_line,
|
||||
makeRow("Software", pageComps["Software_input"].View()),
|
||||
split_line,
|
||||
)
|
||||
|
||||
buttons := m.renderNavButtons()
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
inputs.String(), "",
|
||||
buttons, "",
|
||||
// 按钮区域
|
||||
btnArea := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
pageComps["next_btn"].View(),
|
||||
pageComps["prev_btn"].View(),
|
||||
)
|
||||
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
|
||||
// 页面整体
|
||||
pageContent := lipgloss.JoinVertical(
|
||||
lipgloss.Center,
|
||||
titleStyle.Render("基础信息配置(页2/6)"),
|
||||
formContent,
|
||||
btnArea,
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// publicNetworkView 公网设置页面
|
||||
func (m model) publicNetworkView() string {
|
||||
title := titleStyle.Render("Public Network Configuration")
|
||||
func renderPublicNetworkPage(m model) string {
|
||||
pageComps := m.pageComponents[PagePublicNetwork]
|
||||
|
||||
// 拼接公网网络表单
|
||||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
split_line,
|
||||
makeRow("PublicInterface", pageComps["PublicInterface_input"].View()),
|
||||
split_line,
|
||||
makeRow("PublicIPAddress", pageComps["PublicIPAddress_input"].View()),
|
||||
split_line,
|
||||
makeRow("PublicNetmask", pageComps["PublicNetmask_input"].View()),
|
||||
split_line,
|
||||
makeRow("PublicGateway", pageComps["PublicGateway_input"].View()),
|
||||
split_line,
|
||||
)
|
||||
|
||||
// 按钮区域
|
||||
btnArea := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
pageComps["next_btn"].View(),
|
||||
pageComps["prev_btn"].View(),
|
||||
)
|
||||
|
||||
networkInterfaces := getNetworkInterfaces()
|
||||
autoDetect := infoStyle.Render(
|
||||
"[*] Auto Detect Network Interfaces: " + strings.Join(networkInterfaces, ", "))
|
||||
"[*] Auto Detect Interfaces: " + strings.Join(networkInterfaces, ", "))
|
||||
|
||||
var inputs strings.Builder
|
||||
for i, ti := range m.textInputs {
|
||||
info := fmt.Sprintf("%-20s|", m.inputLabels[i])
|
||||
input := inputBox.Render(info + ti.View())
|
||||
inputs.WriteString(input + "\n")
|
||||
}
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
|
||||
buttons := m.renderNavButtons()
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
autoDetect, "",
|
||||
inputs.String(), "",
|
||||
buttons, "",
|
||||
// 页面整体
|
||||
pageContent := lipgloss.JoinVertical(
|
||||
lipgloss.Center,
|
||||
titleStyle.Render("公网网络配置(页3/6)"),
|
||||
autoDetect,
|
||||
formContent,
|
||||
btnArea,
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// internalNetworkView 内网配置页面
|
||||
func (m model) internalNetworkView() string {
|
||||
title := titleStyle.Render("Internal Network Configuration")
|
||||
func renderInternalNetworkPage(m model) string {
|
||||
pageComps := m.pageComponents[PageInternalNetwork]
|
||||
|
||||
networkInterfaces := getNetworkInterfaces()
|
||||
autoDetect := infoStyle.Render(
|
||||
"[*] Auto Detect Network Interfaces: " + strings.Join(networkInterfaces, ", "))
|
||||
// 拼接内网网络表单
|
||||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
split_line,
|
||||
makeRow("InternalInterface", pageComps["InternalInterface_input"].View()),
|
||||
split_line,
|
||||
makeRow("InternalIPAddress", pageComps["InternalIPAddress_input"].View()),
|
||||
split_line,
|
||||
makeRow("InternalNetmask", pageComps["InternalNetmask_input"].View()),
|
||||
split_line,
|
||||
)
|
||||
|
||||
var inputs strings.Builder
|
||||
for i, ti := range m.textInputs {
|
||||
info := fmt.Sprintf("%-20s|", m.inputLabels[i])
|
||||
input := inputBox.Render(info + ti.View())
|
||||
inputs.WriteString(input + "\n")
|
||||
}
|
||||
// 按钮区域
|
||||
btnArea := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
pageComps["next_btn"].View(),
|
||||
pageComps["prev_btn"].View(),
|
||||
)
|
||||
|
||||
buttons := m.renderNavButtons()
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
autoDetect, "",
|
||||
inputs.String(), "",
|
||||
buttons, "",
|
||||
// 页面整体
|
||||
pageContent := lipgloss.JoinVertical(
|
||||
lipgloss.Center,
|
||||
titleStyle.Render("内网网络配置(页4/6)"),
|
||||
formContent,
|
||||
btnArea,
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// dnsView DNS 配置页面
|
||||
func (m model) dnsView() string {
|
||||
title := titleStyle.Render("DNS Configuration")
|
||||
func renderDNSPage(m model) string {
|
||||
pageComps := m.pageComponents[PageDNS]
|
||||
|
||||
var inputs strings.Builder
|
||||
for i, ti := range m.textInputs {
|
||||
info := fmt.Sprintf("%-10s|", m.inputLabels[i])
|
||||
input := inputBox.Render(info + ti.View())
|
||||
inputs.WriteString(input + "\n")
|
||||
}
|
||||
// 拼接 DNS 表单
|
||||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
split_line,
|
||||
makeRow("Pri DNS", pageComps["Pri_DNS_input"].View()),
|
||||
split_line,
|
||||
makeRow("Sec DNS", pageComps["Sec_DNS_input"].View()),
|
||||
split_line,
|
||||
)
|
||||
|
||||
buttons := m.renderNavButtons()
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
// 按钮区域
|
||||
btnArea := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
pageComps["next_btn"].View(),
|
||||
pageComps["prev_btn"].View(),
|
||||
)
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
inputs.String(), "",
|
||||
buttons, "",
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
|
||||
// 页面整体
|
||||
pageContent := lipgloss.JoinVertical(
|
||||
lipgloss.Center,
|
||||
titleStyle.Render("DNS 配置(页5/6)"),
|
||||
formContent,
|
||||
btnArea,
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// summaryView 总结页面
|
||||
func (m model) summaryView() string {
|
||||
title := titleStyle.Render("Summary")
|
||||
subtitle := subTitleStyle.Render("Please confirm the following configuration information")
|
||||
func renderSummaryPage(m model) string {
|
||||
pageComps := m.pageComponents[PageSummary]
|
||||
|
||||
summary := summaryBox.Render(fmt.Sprintf(`
|
||||
+----------------------------------------------------+
|
||||
Basic Information
|
||||
+----------------------------------------------------+
|
||||
Homepage : %-38s
|
||||
Hostname : %-35s
|
||||
Country : %-31s
|
||||
Region : %-31s
|
||||
Timezone : %-38s
|
||||
Homepage : %-38s
|
||||
+----------------------------------------------------+
|
||||
Database Configuration
|
||||
+----------------------------------------------------+
|
||||
Database Path : %-38s
|
||||
Software : %-33s
|
||||
+----------------------------------------------------+
|
||||
Public Network Configuration
|
||||
+----------------------------------------------------+
|
||||
Public Interface : %-38s
|
||||
Public IP : %-41s
|
||||
Public Netmask : %-38s
|
||||
Public Gateway : %-38s
|
||||
+----------------------------------------------------+
|
||||
Internal Network Configuration
|
||||
+----------------------------------------------------+
|
||||
Internal Interface: %-38s
|
||||
Internal IP : %-41s
|
||||
Internal Netmask : %-38s
|
||||
+----------------------------------------------------+
|
||||
DNS Configuration
|
||||
+----------------------------------------------------+
|
||||
Primary DNS : %-37s
|
||||
Secondary DNS : %-37s
|
||||
+----------------------------------------------------+
|
||||
`,
|
||||
m.config.HomePage,
|
||||
m.config.Hostname,
|
||||
m.config.Country,
|
||||
m.config.Region,
|
||||
m.config.Timezone,
|
||||
m.config.HomePage,
|
||||
m.config.DBAddress,
|
||||
m.config.DataAddress,
|
||||
m.config.PublicInterface,
|
||||
m.config.PublicIPAddress,
|
||||
m.config.PublicNetmask,
|
||||
m.config.PublicGateway,
|
||||
m.config.InternalInterface,
|
||||
m.config.InternalIPAddress,
|
||||
m.config.InternalNetmask,
|
||||
m.config.DNSPrimary,
|
||||
m.config.DNSSecondary,
|
||||
))
|
||||
// 拼接 Summary 表单
|
||||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||||
split_line,
|
||||
makeRow("Hostname", m.config.Hostname),
|
||||
split_line,
|
||||
makeRow("Country", m.config.Country),
|
||||
split_line,
|
||||
makeRow("Region", m.config.Region),
|
||||
split_line,
|
||||
makeRow("Timezone", m.config.Timezone),
|
||||
split_line,
|
||||
makeRow("Homepage", m.config.HomePage),
|
||||
split_line,
|
||||
makeRow("DBPath", m.config.DBAddress),
|
||||
split_line,
|
||||
makeRow("Software", m.config.Software),
|
||||
split_line,
|
||||
makeRow("PublicInterface", m.config.PublicInterface),
|
||||
split_line,
|
||||
makeRow("PublicIPAddress", m.config.PublicIPAddress),
|
||||
split_line,
|
||||
makeRow("PublicNetmask", m.config.PublicNetmask),
|
||||
split_line,
|
||||
makeRow("PublicGateway", m.config.PublicGateway),
|
||||
split_line,
|
||||
makeRow("InternalInterface", m.config.InternalInterface),
|
||||
split_line,
|
||||
makeRow("InternalIPAddress", m.config.InternalIPAddress),
|
||||
split_line,
|
||||
makeRow("InternalNetmask", m.config.InternalNetmask),
|
||||
split_line,
|
||||
makeRow("Pri DNS", m.config.DNSPrimary),
|
||||
split_line,
|
||||
makeRow("Sec DNS", m.config.DNSSecondary),
|
||||
split_line,
|
||||
)
|
||||
|
||||
var buttons string
|
||||
if m.focusIndex == 0 {
|
||||
buttons = selectedButton.Render("[>] Start Initialization") + " " + normalButton.Render("[ ] Cancel")
|
||||
} else {
|
||||
buttons = normalButton.Render("[>] Start Initialization") + " " + selectedButton.Render("[ ] Cancel")
|
||||
}
|
||||
// 按钮区域
|
||||
btnArea := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
pageComps["confirm_btn"].View(),
|
||||
pageComps["cancel_btn"].View(),
|
||||
)
|
||||
|
||||
hint := hintStyle.Render("Use Up/Down OR Tab Change,Enter Confirm")
|
||||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center,
|
||||
title, "",
|
||||
subtitle, "",
|
||||
summary, "",
|
||||
buttons, "",
|
||||
// 页面整体
|
||||
pageContent := lipgloss.JoinVertical(
|
||||
lipgloss.Center,
|
||||
titleStyle.Render("确认信息(页6/6)"),
|
||||
formContent,
|
||||
btnArea,
|
||||
hint,
|
||||
)
|
||||
|
||||
return appStyle.Render(pageContent)
|
||||
}
|
||||
|
||||
// progressView 进度条
|
||||
func progressView(current PageType, total int) string {
|
||||
progress := ""
|
||||
for i := 0; i < total; i++ {
|
||||
if i < int(current) {
|
||||
progress += "[+]"
|
||||
} else if i == int(current) {
|
||||
progress += "[-]"
|
||||
} else {
|
||||
progress += "[ ]"
|
||||
}
|
||||
if i < total-1 {
|
||||
progress += " "
|
||||
}
|
||||
}
|
||||
labels := []string{"License", "Data", "Network", "Network", "DNS", "Summary"}
|
||||
label := labelStyle.Render(labels[current])
|
||||
return progressStyle.Render(progress) + " " + label
|
||||
}
|
||||
|
||||
// successView 成功视图
|
||||
func successView() string {
|
||||
return containerStyle.Render(lipgloss.JoinVertical(lipgloss.Center,
|
||||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||||
successTitle.Render("Initialization Completed!"), "",
|
||||
successMsg.Render("System configuration has been saved, and the system is initializing..."), "",
|
||||
hintStyle.Render("Press any key to exit"),
|
||||
))
|
||||
successMsg.Render(
|
||||
"System configuration has been saved, and the system is initializing..."), "",
|
||||
)
|
||||
return appStyle.Render(content)
|
||||
}
|
||||
|
||||
// quitView 退出视图
|
||||
func quitView() string {
|
||||
return containerStyle.Render(lipgloss.JoinVertical(lipgloss.Center,
|
||||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||||
errorTitle.Render("Canceled"), "",
|
||||
errorMsg.Render("Initialization canceled, no configuration saved"),
|
||||
))
|
||||
)
|
||||
return appStyle.Render(content)
|
||||
}
|
||||
|
||||
// errorView 错误视图
|
||||
func errorView(err error) string {
|
||||
return containerStyle.Render(lipgloss.JoinVertical(lipgloss.Center,
|
||||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||||
errorTitle.Render("Error"), "",
|
||||
errorMsg.Render(err.Error()), "",
|
||||
hintStyle.Render("Press Ctrl+C to exit"),
|
||||
))
|
||||
}
|
||||
|
||||
// navButtons 导航按钮
|
||||
func navButtons(m model, prev, next string) string {
|
||||
var btns string
|
||||
if m.currentPage == 0 {
|
||||
btns = normalButton.Render(next) + " " + selectedButton.Render(prev)
|
||||
} else {
|
||||
btns = selectedButton.Render(next) + " " + normalButton.Render(prev)
|
||||
}
|
||||
return btns
|
||||
}
|
||||
|
||||
func (m model) renderNavButtons() string {
|
||||
var prevBtn, nextBtn string
|
||||
|
||||
switch m.focusType {
|
||||
case FocusTypePrev:
|
||||
// 焦点在"上一步"
|
||||
nextBtn = normalButton.Render(" Next ")
|
||||
prevBtn = selectedButton.Render(" << Prev >>")
|
||||
case FocusTypeNext:
|
||||
// 焦点在"下一步"
|
||||
nextBtn = selectedButton.Render(" << Next >>")
|
||||
prevBtn = normalButton.Render(" Prev ")
|
||||
default:
|
||||
// 焦点在输入框
|
||||
nextBtn = normalButton.Render(" Next ")
|
||||
prevBtn = normalButton.Render(" Prev ")
|
||||
}
|
||||
|
||||
return lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
nextBtn,
|
||||
" ",
|
||||
prevBtn,
|
||||
)
|
||||
return appStyle.Render(content)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user