360 lines
9.9 KiB
Go
360 lines
9.9 KiB
Go
package wizard
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"github.com/charmbracelet/lipgloss"
|
||
)
|
||
|
||
var split_line = splitlineStyle.Render(
|
||
"───────────────────────────────────────────────────────────────")
|
||
|
||
// View 渲染视图
|
||
func (m model) View() string {
|
||
if m.done {
|
||
return successView()
|
||
}
|
||
if m.quitting {
|
||
return quitView()
|
||
}
|
||
if m.err != nil {
|
||
return errorView(m.err)
|
||
}
|
||
|
||
var pageContent string
|
||
switch m.currentPage {
|
||
case PageAgreement:
|
||
pageContent = renderLicensePage(m)
|
||
case PageData:
|
||
pageContent = renderDataInfoPage(m)
|
||
case PagePublicNetwork:
|
||
pageContent = renderPublicNetworkPage(m)
|
||
case PageInternalNetwork:
|
||
pageContent = renderInternalNetworkPage(m)
|
||
case PageDNS:
|
||
pageContent = renderDNSPage(m)
|
||
case PageSummary:
|
||
pageContent = renderSummaryPage(m)
|
||
|
||
default:
|
||
pageContent = appStyle.Render("无效页面")
|
||
}
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
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")
|
||
|
||
licenseText := `
|
||
───────────────────────────────────────────────────────────────
|
||
1. License Grant
|
||
This software grants you a non-exclusive, non-transferable
|
||
license to use it.
|
||
2. Disclaimer of Warranties
|
||
This software is provided "as is" without any warranties,
|
||
whether express or implied.
|
||
3. Limitation of Liability
|
||
This software is provided without warranty of any kind,
|
||
either express or implied.
|
||
In no event shall the author be liable for any damages
|
||
arising out of the use of this software.
|
||
4. Termination of Agreement
|
||
If you violate any of the terms of this agreement,
|
||
the license will automatically terminate.
|
||
───────────────────────────────────────────────────────────────
|
||
PLEASE READ THE ABOVE TERMS CAREFULLY AND CLICK "ACCEPT"
|
||
TO AGREE AND FOLLOW THIS AGREEMENT.
|
||
───────────────────────────────────────────────────────────────
|
||
`
|
||
|
||
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 Left/Right OR Tab Change,Enter Confirm")
|
||
pageContent := lipgloss.JoinVertical(lipgloss.Center,
|
||
title, "",
|
||
licenseTextStyle.Render(licenseText),
|
||
lipgloss.JoinHorizontal(lipgloss.Center, acceptBtn, rejectBtn),
|
||
|
||
hint,
|
||
)
|
||
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
// ---------------- 页2:基础信息页渲染 ----------------
|
||
func renderDataInfoPage(m model) string {
|
||
pageComps := m.pageComponents[PageData]
|
||
|
||
// 拼接基础信息表单
|
||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||
split_line,
|
||
makeRow("Homepage", pageComps["Homepage_input"].View()),
|
||
split_line,
|
||
makeRow("ClusterName", pageComps["ClusterName_input"].View()),
|
||
split_line,
|
||
makeRow("Country", pageComps["Country_input"].View()),
|
||
split_line,
|
||
makeRow("State", pageComps["State_input"].View()),
|
||
split_line,
|
||
makeRow("City", pageComps["City_input"].View()),
|
||
split_line,
|
||
makeRow("Contact", pageComps["Contact_input"].View()),
|
||
split_line,
|
||
makeRow("Timezone", pageComps["Timezone_input"].View()),
|
||
split_line,
|
||
makeRow("DistroDir", pageComps["DistroDir_input"].View()),
|
||
split_line,
|
||
)
|
||
|
||
// 按钮区域
|
||
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)
|
||
}
|
||
|
||
func renderPublicNetworkPage(m model) string {
|
||
pageComps := m.pageComponents[PagePublicNetwork]
|
||
|
||
// 拼接公网网络表单
|
||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||
split_line,
|
||
makeRow("PublicHostname", pageComps["PublicHostname_input"].View()),
|
||
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,
|
||
makeRow("PublicDomain", pageComps["PublicDomain_input"].View()),
|
||
split_line,
|
||
makeRow("PublicMTU", pageComps["PublicMTU_input"].View()),
|
||
split_line,
|
||
)
|
||
|
||
// 按钮区域
|
||
btnArea := lipgloss.JoinHorizontal(
|
||
lipgloss.Center,
|
||
pageComps["next_btn"].View(),
|
||
pageComps["prev_btn"].View(),
|
||
)
|
||
|
||
networkInterfaces := getNetworkInterfaces()
|
||
autoDetect := infoStyle.Render(
|
||
"[*] Auto Detect Interfaces: " + strings.Join(networkInterfaces, ", "))
|
||
|
||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||
|
||
// 页面整体
|
||
pageContent := lipgloss.JoinVertical(
|
||
lipgloss.Center,
|
||
titleStyle.Render("公网网络配置(页3/6)"),
|
||
autoDetect,
|
||
formContent,
|
||
btnArea,
|
||
hint,
|
||
)
|
||
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
func renderInternalNetworkPage(m model) string {
|
||
pageComps := m.pageComponents[PageInternalNetwork]
|
||
|
||
// 拼接内网网络表单
|
||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||
split_line,
|
||
makeRow("PrivateHostname", pageComps["PrivateHostname_input"].View()),
|
||
split_line,
|
||
makeRow("PrivateInterface", pageComps["PrivateInterface_input"].View()),
|
||
split_line,
|
||
makeRow("PrivateIPAddress", pageComps["PrivateIPAddress_input"].View()),
|
||
split_line,
|
||
makeRow("PrivateNetmask", pageComps["PrivateNetmask_input"].View()),
|
||
split_line,
|
||
makeRow("PrivateDomain", pageComps["PrivateDomain_input"].View()),
|
||
split_line,
|
||
makeRow("PrivateMTU", pageComps["PrivateMTU_input"].View()),
|
||
split_line,
|
||
)
|
||
|
||
// 按钮区域
|
||
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("内网网络配置(页4/6)"),
|
||
formContent,
|
||
btnArea,
|
||
hint,
|
||
)
|
||
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
func renderDNSPage(m model) string {
|
||
pageComps := m.pageComponents[PageDNS]
|
||
|
||
// 拼接 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,
|
||
)
|
||
|
||
// 按钮区域
|
||
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("DNS 配置(页5/6)"),
|
||
formContent,
|
||
btnArea,
|
||
hint,
|
||
)
|
||
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
func renderSummaryPage(m model) string {
|
||
pageComps := m.pageComponents[PageSummary]
|
||
|
||
// 拼接 Summary 表单
|
||
formContent := lipgloss.JoinVertical(lipgloss.Center,
|
||
split_line,
|
||
makeRow("ClusterName", m.config.ClusterName),
|
||
split_line,
|
||
makeRow("Country", m.config.Country),
|
||
split_line,
|
||
makeRow("State", m.config.State),
|
||
split_line,
|
||
makeRow("City", m.config.City),
|
||
split_line,
|
||
makeRow("Contact", m.config.Contact),
|
||
split_line,
|
||
makeRow("Timezone", m.config.Timezone),
|
||
split_line,
|
||
makeRow("Homepage", m.config.HomePage),
|
||
split_line,
|
||
makeRow("DBPath", m.config.DBAddress),
|
||
split_line,
|
||
makeRow("DistroDir", m.config.DistroDir),
|
||
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("PrivateInterface", m.config.PrivateInterface),
|
||
split_line,
|
||
makeRow("PrivateIPAddress", m.config.PrivateIPAddress),
|
||
split_line,
|
||
makeRow("PrivateNetmask", m.config.PrivateNetmask),
|
||
split_line,
|
||
makeRow("PrivateMTU", m.config.PrivateMTU),
|
||
split_line,
|
||
makeRow("Pri DNS", m.config.DNSPrimary),
|
||
split_line,
|
||
makeRow("Sec DNS", m.config.DNSSecondary),
|
||
split_line,
|
||
)
|
||
|
||
// 按钮区域
|
||
btnArea := lipgloss.JoinHorizontal(
|
||
lipgloss.Center,
|
||
pageComps["confirm_btn"].View(),
|
||
pageComps["cancel_btn"].View(),
|
||
)
|
||
|
||
hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm")
|
||
|
||
// 页面整体
|
||
pageContent := lipgloss.JoinVertical(
|
||
lipgloss.Center,
|
||
titleStyle.Render("确认信息(页6/6)"),
|
||
formContent,
|
||
btnArea,
|
||
hint,
|
||
)
|
||
|
||
return appStyle.Render(pageContent)
|
||
}
|
||
|
||
func successView() string {
|
||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||
successTitle.Render("Initialization Completed!"), "",
|
||
successMsg.Render(
|
||
"System configuration has been saved, and the system is initializing..."), "",
|
||
)
|
||
return appStyle.Render(content)
|
||
}
|
||
|
||
func quitView() string {
|
||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||
split_line,
|
||
errorTitle.Render("Canceled"), "",
|
||
errorMsg.Render("Initialization canceled, no configuration saved"),
|
||
split_line,
|
||
"\n",
|
||
)
|
||
return quitStyle.Render(content)
|
||
}
|
||
|
||
func errorView(err error) string {
|
||
content := lipgloss.JoinVertical(lipgloss.Center,
|
||
errorTitle.Render("Error"), "",
|
||
errorMsg.Render(err.Error()), "",
|
||
hintStyle.Render("Press Ctrl+C to exit"),
|
||
)
|
||
return appStyle.Render(content)
|
||
}
|