Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(config): adds help text via tabbed keybindings #64

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions cmd/cli/commands/config/config_contributoor.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,14 @@ func (p *ContributoorSettingsPage) initPage() {
}

// Add our form fields.
form.AddDropDown("Log Level", logLevels, currentLogLevelIndex, func(option string, index int) {
form.AddDropDown("Log Level", logLevels, currentLogLevelIndex, func(text string, index int) {
p.description.SetText("Set the logging verbosity level. Debug and Trace provide more detailed output.")
})

form.AddDropDown("Run Mode", runModeLabels, currentRunModeIndex, func(option string, index int) {
if option == config.RunMethod_RUN_METHOD_DOCKER.String() {
form.AddDropDown("Run Mode", runModeLabels, currentRunModeIndex, func(text string, index int) {
if text == strings.ToLower(config.RunMethod_RUN_METHOD_DOCKER.DisplayName()) {
p.description.SetText("Run using Docker containers (recommended)")
} else if runModes[index] == config.RunMethod_RUN_METHOD_SYSTEMD {
} else if text == getServiceManagerLabel() {
p.description.SetText(getServiceManagerDescription())
} else {
p.description.SetText("Run directly as a binary on your system")
Expand All @@ -139,7 +139,15 @@ func (p *ContributoorSettingsPage) initPage() {
// Define key bindings for the save button.
saveButton.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyTab, tcell.KeyBacktab:
case tcell.KeyTab:
// When tabbing from save button, go back to first form item.
form.SetFocus(0)
p.display.app.SetFocus(form)

return nil
case tcell.KeyBacktab:
// When back-tabbing from save button, go to last form item.
form.SetFocus(form.GetFormItemCount() - 1)
p.display.app.SetFocus(form)

return nil
Expand All @@ -150,30 +158,33 @@ func (p *ContributoorSettingsPage) initPage() {

// Define key bindings for the form.
form.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
// Get the currently focused item.
formIndex, _ := form.GetFocusedItemIndex()

switch event.Key() {
case tcell.KeyTab:
// If we're on the last form item, move to save button.
if formIndex == form.GetFormItemCount()-1 {
p.display.app.SetFocus(saveButton)

return nil
}

return event
case tcell.KeyBacktab:
// If we're on the first form item, move to save button.
if formIndex == 0 {
p.display.app.SetFocus(saveButton)

return nil
}

return event
default:
return event
}

return event
})

// Set initial focus to first form item
form.SetFocus(0)
p.display.app.SetFocus(form)

// We wrap the form in a frame to add a border and title.
formFrame := tview.NewFrame(form)
formFrame.SetBorder(true)
Expand Down Expand Up @@ -213,11 +224,10 @@ func validateAndUpdateContributoor(p *ContributoorSettingsPage) {

_, logLevelText := logLevel.GetCurrentOption()
runModeIndex, _ := runMode.GetCurrentOption()
runModeText := runModes[runModeIndex]

if err := p.display.sidecarCfg.Update(func(cfg *config.Config) {
cfg.LogLevel = logLevelText
cfg.RunMethod = runModeText
cfg.RunMethod = runModes[runModeIndex]
}); err != nil {
p.openErrorModal(err)

Expand Down
45 changes: 35 additions & 10 deletions cmd/cli/commands/config/config_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,14 @@ func (p *NetworkConfigPage) initPage() {
form.AddDropDown("Network", networks, currentNetworkIndex, func(option string, index int) {
p.description.SetText(networkDescriptions[option])
})
form.AddInputField("Beacon Node Address", p.display.sidecarCfg.Get().BeaconNodeAddress, 0, nil, nil)

beaconInput := tview.NewInputField().
SetLabel("Beacon Node Address: ").
SetText(p.display.sidecarCfg.Get().BeaconNodeAddress)
beaconInput.SetFocusFunc(func() {
p.description.SetText("The address of your beacon node (e.g., http://127.0.0.1:5052)")
})
form.AddFormItem(beaconInput)

// Add Docker network dropdown if using Docker.
if p.display.sidecarCfg.Get().RunMethod == config.RunMethod_RUN_METHOD_DOCKER {
Expand Down Expand Up @@ -144,10 +151,20 @@ func (p *NetworkConfigPage) initPage() {
}
}

networkDropdown.SetFocusFunc(func() {
p.description.SetText("You can optionally attach the Contributoor container to one of your existing Docker networks.")
})

form.AddFormItem(networkDropdown)
}

form.AddInputField("Optional Metrics Address", p.display.sidecarCfg.Get().MetricsAddress, 0, nil, nil)
metricsInput := tview.NewInputField().
SetLabel("Optional Metrics Address: ").
SetText(p.display.sidecarCfg.Get().MetricsAddress)
metricsInput.SetFocusFunc(func() {
p.description.SetText("The optional address to expose contributoor metrics on (e.g., :9090). This is NOT the address of your Beacon Node prometheus metrics. If you don't know what this is - leave it empty.")
})
form.AddFormItem(metricsInput)

// Add a save button and ensure we validate the input.
saveButton := tview.NewButton(tui.ButtonSaveSettings)
Expand All @@ -160,8 +177,16 @@ func (p *NetworkConfigPage) initPage() {
// Define key bindings for the save button.
saveButton.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyTab, tcell.KeyBacktab:
p.display.app.SetFocus(form)
case tcell.KeyTab:
// When tabbing from save button, go back to first form item.
p.form.SetFocus(0)
p.display.app.SetFocus(p.form)

return nil
case tcell.KeyBacktab:
// When back-tabbing from save button, go to last form item.
p.form.SetFocus(p.form.GetFormItemCount() - 1)
p.display.app.SetFocus(p.form)

return nil
}
Expand All @@ -182,22 +207,22 @@ func (p *NetworkConfigPage) initPage() {

return nil
}

return event
case tcell.KeyBacktab:
// If we're on the first form item, move to save button.
if formIndex == 0 {
p.display.app.SetFocus(saveButton)

return nil
}

return event
default:
return event
}

return event
})

// Set initial focus to first form item
form.SetFocus(0)
p.display.app.SetFocus(form)

// We wrap the form in a frame to add a border and title.
formFrame := tview.NewFrame(form)
formFrame.SetBorder(true)
Expand Down
64 changes: 49 additions & 15 deletions cmd/cli/commands/config/config_output_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,43 @@ func (p *OutputServerConfigPage) initPage() {
}

// Add the server address field.
form.AddInputField("Server Address", defaultAddress, 0, nil, nil)
serverInput := tview.NewInputField().
SetLabel("Server Address").
SetText(defaultAddress)
serverInput.SetFocusFunc(func() {
p.description.SetText("The address of your custom output server (e.g., myserver.com:443)")
})
form.AddFormItem(serverInput)

// Add the username and password fields.
username, password := getCredentialsFromConfig(p.display.sidecarCfg.Get())
form.AddInputField("Username", username, 0, nil, nil)
form.AddPasswordField("Password", password, 0, '*', nil)
usernameInput := tview.NewInputField().
SetLabel("Username").
SetText(username)
usernameInput.SetFocusFunc(func() {
p.description.SetText("Your output server username for authentication")
})
form.AddFormItem(usernameInput)

form.AddPasswordField("Password", password, 0, '*', nil).
SetFocusFunc(func() {
p.description.SetText("Your output server password for authentication")
})
} else {
// Otherwise, it's an ethPandaOps server.
username, password := getCredentialsFromConfig(p.display.sidecarCfg.Get())
form.AddInputField("Username", username, 0, nil, nil)
form.AddPasswordField("Password", password, 0, '*', nil)
usernameInput := tview.NewInputField().
SetLabel("Username").
SetText(username)
usernameInput.SetFocusFunc(func() {
p.description.SetText("Your ethPandaOps platform username for authentication")
})
form.AddFormItem(usernameInput)

form.AddPasswordField("Password", password, 0, '*', nil).
SetFocusFunc(func() {
p.description.SetText("Your ethPandaOps platform password for authentication")
})
}

p.display.app.SetFocus(form)
Expand All @@ -160,7 +186,15 @@ func (p *OutputServerConfigPage) initPage() {
// Define key bindings for the save button.
saveButton.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyTab, tcell.KeyBacktab:
case tcell.KeyTab:
// When tabbing from save button, go back to first form item.
form.SetFocus(0)
p.display.app.SetFocus(form)

return nil
case tcell.KeyBacktab:
// When back-tabbing from save button, go to last form item.
form.SetFocus(form.GetFormItemCount() - 1)
p.display.app.SetFocus(form)

return nil
Expand All @@ -171,33 +205,33 @@ func (p *OutputServerConfigPage) initPage() {

// Define key bindings for the form.
form.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
// Get the currently focused item
// Get the currently focused item.
formIndex, _ := form.GetFocusedItemIndex()

switch event.Key() {
case tcell.KeyTab:
// If we're on the last form item, move to save button
// If we're on the last form item, move to save button.
if formIndex == form.GetFormItemCount()-1 {
p.display.app.SetFocus(saveButton)

return nil
}

return event
case tcell.KeyBacktab:
// If we're on the first form item, move to save button
// If we're on the first form item, move to save button.
if formIndex == 0 {
p.display.app.SetFocus(saveButton)

return nil
}

return event
default:
return event
}

return event
})

// Set initial focus to first form item
form.SetFocus(0)
p.display.app.SetFocus(form)

// We wrap the form in a frame to add a border and title.
formFrame := tview.NewFrame(form)
formFrame.SetBorder(true)
Expand Down
1 change: 0 additions & 1 deletion internal/tui/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func CreatePageFrame(opts PageFrameOptions) *tview.Frame {
// Set navigation text based on context
switch opts.HelpType {
case HelpSettings:
frame.AddText("Navigation: Settings > "+opts.Title, true, tview.AlignLeft, tcell.ColorWhite)
frame.AddText("Tab: Go to the Buttons Ctrl+C: Quit without Saving", false, tview.AlignCenter, tcell.ColorWhite)
frame.AddText("Arrow keys: Navigate Space/Enter: Select", false, tview.AlignCenter, tcell.ColorWhite)
default: // HelpWizard
Expand Down
Loading