refact: improve input prompt and button layout in dashboard
rabbitprincess committed
May 8, 2026 at 22:56 UTC
93fa0d3135c7b79d337759e37d5ee6cb14edafc1
1 file changed
+13
-46
cmd/portal-tunnel/agent/dashboard.go
+13
-46
@@ -19,8 +19,9 @@ import (
19
)
20
21
const (
22
- agentDashboardPollInterval = 2 * time.Second
23
- agentDashboardMinRelayRows = 1
22
+ agentDashboardPollInterval = 2 * time.Second
23
+ agentDashboardMinRelayRows = 1
24
+ agentDashboardTunnelInputMaxWidth = 80
25
)
26
27
type agentDashboardAction int
@@ -102,11 +103,12 @@ var (
103
func RunDashboard(configPath, stateDir string) error {
104
input := textinput.New()
105
input.CharLimit = 512
105
- input.Prompt = ""
106
- input.Placeholder = "name port"
106
+ input.Prompt = "New tunnel: "
107
+ input.Placeholder = "name target (Examples: myname 3000)"
108
+ input.PromptStyle = agentDashboardSectionStyle
109
input.TextStyle = agentDashboardInputStyle
110
input.PlaceholderStyle = agentDashboardMutedStyle
109
- input.Width = 32
111
+ input.Width = agentDashboardTunnelInputMaxWidth
112
_ = input.Focus()
113
114
_, err := tea.NewProgram(agentDashboardModel{
@@ -126,8 +128,9 @@ func (m agentDashboardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
128
case tea.WindowSizeMsg:
129
m.width = msg.Width
130
m.height = msg.Height
129
- buttonsWidth := lipgloss.Width("[ Add Tunnel ]") + lipgloss.Width("[ Delete ]") + 2
130
- m.input.Width = max(1, min(32, msg.Width-buttonsWidth))
131
+ availableWidth := msg.Width - lipgloss.Width(m.input.Prompt)
132
+ clearWidth := lipgloss.Width(m.input.Prompt) + lipgloss.Width(m.input.Placeholder)
133
+ m.input.Width = max(clearWidth, min(agentDashboardTunnelInputMaxWidth, availableWidth))
134
return m, nil
135
case agentDashboardTickMsg:
136
return m, tea.Batch(agentDashboardFetchStatus(m.stateDir), agentDashboardTick())
@@ -399,7 +402,7 @@ func (m agentDashboardModel) addTunnelFromInput() (tea.Model, tea.Cmd) {
402
}
403
fields := strings.Fields(value)
404
if len(fields) < 2 {
402
- m.err = fmt.Errorf("use: name port")
405
+ m.err = fmt.Errorf("use: name target")
406
return m, nil
407
}
408
name := strings.Join(fields[:len(fields)-1], " ")
@@ -613,10 +616,11 @@ func (m agentDashboardModel) layout() agentDashboardView {
616
func (m agentDashboardModel) renderTunnelsSection(width int) agentDashboardView {
617
var pane agentDashboardView
618
pane.addStyled(width, agentDashboardSectionStyle, "Tunnels")
616
- pane.addInputButton(width, m.input.View(),
619
+ pane.addButtons(width,
620
agentDashboardButton{label: "Add Tunnel", action: agentDashboardActionAddTunnel, disabled: strings.TrimSpace(m.input.Value()) == ""},
621
agentDashboardButton{label: "Delete", action: agentDashboardActionDeleteTunnel, disabled: len(m.status.Tunnels) == 0},
622
)
623
+ pane.addLine(m.input.View())
624
tunnelRowWidth := agentDashboardTunnelTableWidth(width, m.status.Tunnels)
625
pane.addLine(agentDashboardMutedStyle.Render(agentDashboardTunnelRow(tunnelRowWidth, "STATUS", "TARGET", "TUNNEL")))
626
@@ -762,43 +766,6 @@ func (v *agentDashboardView) addButtons(width int, buttons ...agentDashboardButt
766
v.regions = append(v.regions, regions...)
767
}
768
765
-func (v *agentDashboardView) addInputButton(width int, input string, buttons ...agentDashboardButton) {
766
- if width <= 0 {
767
- width = 1
768
- }
769
- line := agentDashboardFit(input, width)
770
- lineWidth := lipgloss.Width(line)
771
- y := len(v.lines)
772
- for _, button := range buttons {
773
- if lineWidth >= width {
774
- break
775
- }
776
- if lineWidth > 0 {
777
- line += " "
778
- lineWidth++
779
- }
780
- buttonText := agentDashboardFit("[ "+button.label+" ]", width-lineWidth)
781
- buttonWidth := lipgloss.Width(buttonText)
782
- if buttonWidth == 0 {
783
- break
784
- }
785
- buttonStyle := agentDashboardButtonStyle
786
- if button.disabled {
787
- buttonStyle = agentDashboardDisabledStyle
788
- } else {
789
- v.regions = append(v.regions, agentDashboardRegion{
790
- x0: lineWidth,
791
- x1: lineWidth + buttonWidth,
792
- y: y,
793
- action: button.action,
794
- })
795
- }
796
- line += buttonStyle.Render(buttonText)
797
- lineWidth += buttonWidth
798
- }
799
- v.lines = append(v.lines, line)
800
-}
801
-
769
func (v *agentDashboardView) addView(child agentDashboardView) {
770
startY := len(v.lines)
771
v.lines = append(v.lines, child.lines...)