Files
Honandmcastorina 47c2b6bed9
Lint / lint (push) Waiting to run
Release / Release (push) Waiting to run
Scan for secrets / test (push) Waiting to run
Snifftest / Run Snifftest (push) Waiting to run
Test / test (push) Waiting to run
Test / test-detectors (push) Waiting to run
Test / test-community (push) Waiting to run
Add terminal UI (#1593)
* Init attempt at tui with bubble tea.

Co-authored-by: mcastorina <[email protected]>

* Add starting and source selection options

Co-authored-by: mcastorina <[email protected]>

* Rewrite models into a state machine

* Update source descriptions

* Make subpages implement tea.Model

* Rename page0 and page1 to be more descriptive

* Adjust styling and adding color consts

Co-authored-by: mcastorina <[email protected]>

* Add helper generic function to call Update and type cast

* Setup plumbing for source configuration page

* Use CLI introspection for source configuration (WIP)

* Experiment with table view

* Replace table with form fields

Co-authored-by: mcastorina <[email protected]>

* Change 🔒 to 💸

* Copy components from soft-serve

Co-authored-by: hxnyk <[email protected]>

* Copy styles from soft-serve

Co-authored-by: hxnyk <[email protected]>

* Copy common from soft-serve

Co-authored-by: hxnyk <[email protected]>

* Refactor into pages

This is still a WIP, but the main structure is there.

Co-authored-by: hxnyk <[email protected]>

* Trying out selector for wizard intro

Co-authored-by: mcastorina <[email protected]>

* Use selector with custom View

Co-authored-by: hxnyk <[email protected]>

* Change Item to be an enum

Co-authored-by: hxnyk <[email protected]>

* Add link pages

Co-authored-by: mcastorina <[email protected]>

* Update source select to use selector

Co-authored-by: mcastorina <[email protected]>

* Delete source configure page and add blank tabs

Co-authored-by: hxnyk <[email protected]>

* Add tab placeholder pages for configurationi

Co-authored-by: mcastorina <[email protected]>

* Added headers and style to each tab

Co-authored-by: hxnyk <[email protected]>

* Update with new sources

* Remove kingpin attribute from SourceItem

* Add basic form field and source structuring

* Hookup git form fields with an underlying textinput component

Co-authored-by: hxnyk <[email protected]>

* Update forms for git and github

Co-authored-by: mcastorina <[email protected]>

* Add labels per text input

* Add sources and adjust styling

* add basic trufflehog configuration page

* Add skip button to textinputs component

* Emit and handle textinputs skip/submit button commands

* Don't quit when q is pressed on the sourceConfigurePage

* Build trufflehog command based on source config vals

Co-authored-by: mcastorina <[email protected]>

* Build flags based on truffle config inputs

* Update summary section

* Add generated truffle fields

Co-authored-by: mcastorina <[email protected]>

* update summary to correctly print info

* Go back a page when escape key is pressed

* WIP run page list

Co-authored-by: hxnyk <[email protected]>

* Allow running trufflehog from the run page

Co-authored-by: hxnyk <[email protected]>

* Add option to view help docs

Co-authored-by: mcastorina <[email protected]>

* comment out unused styles and remove unused types

* Capitalize H in TruffleHog

* remove unneeded fmt.Sprintf

---------

Co-authored-by: mcastorina <[email protected]>
2023-08-09 13:13:55 -07:00

123 lines
2.7 KiB
Go

package tabs
import (
"strings"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/trufflesecurity/trufflehog/v3/pkg/tui/common"
)
// SelectTabMsg is a message that contains the index of the tab to select.
type SelectTabMsg int
// ActiveTabMsg is a message that contains the index of the current active tab.
type ActiveTabMsg int
// Tabs is bubbletea component that displays a list of tabs.
type Tabs struct {
common common.Common
tabs []string
activeTab int
TabSeparator lipgloss.Style
TabInactive lipgloss.Style
TabActive lipgloss.Style
TabDot lipgloss.Style
UseDot bool
}
// New creates a new Tabs component.
func New(c common.Common, tabs []string) *Tabs {
r := &Tabs{
common: c,
tabs: tabs,
activeTab: 0,
TabSeparator: c.Styles.TabSeparator,
TabInactive: c.Styles.TabInactive,
TabActive: c.Styles.TabActive,
}
return r
}
// SetSize implements common.Component.
func (t *Tabs) SetSize(width, height int) {
t.common.SetSize(width, height)
}
// Init implements tea.Model.
func (t *Tabs) Init() tea.Cmd {
t.activeTab = 0
return nil
}
// Update implements tea.Model.
func (t *Tabs) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds := make([]tea.Cmd, 0)
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "tab":
t.activeTab = (t.activeTab + 1) % len(t.tabs)
cmds = append(cmds, t.activeTabCmd)
case "shift+tab":
t.activeTab = (t.activeTab - 1 + len(t.tabs)) % len(t.tabs)
cmds = append(cmds, t.activeTabCmd)
}
case tea.MouseMsg:
if msg.Type == tea.MouseLeft {
for i, tab := range t.tabs {
if t.common.Zone.Get(tab).InBounds(msg) {
t.activeTab = i
cmds = append(cmds, t.activeTabCmd)
}
}
}
case SelectTabMsg:
tab := int(msg)
if tab >= 0 && tab < len(t.tabs) {
t.activeTab = int(msg)
}
}
return t, tea.Batch(cmds...)
}
// View implements tea.Model.
func (t *Tabs) View() string {
s := strings.Builder{}
sep := t.TabSeparator
for i, tab := range t.tabs {
style := t.TabInactive.Copy()
prefix := " "
if i == t.activeTab {
style = t.TabActive.Copy()
prefix = t.TabDot.Render("• ")
}
if t.UseDot {
s.WriteString(prefix)
}
s.WriteString(
t.common.Zone.Mark(
tab,
style.Render(tab),
),
)
if i != len(t.tabs)-1 {
s.WriteString(sep.String())
}
}
return lipgloss.NewStyle().
MaxWidth(t.common.Width).
Render(s.String())
}
func (t *Tabs) activeTabCmd() tea.Msg {
return ActiveTabMsg(t.activeTab)
}
// SelectTabCmd is a bubbletea command that selects the tab at the given index.
func SelectTabCmd(tab int) tea.Cmd {
return func() tea.Msg {
return SelectTabMsg(tab)
}
}