-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor log filtering and add tabs (#167)
* Add a new DimensionModel interface We'll implement this interface with other models to a model to handle its own sizing. * Add a new sidebar layout * Add a box layout * Add tabs component * Add wrapper to huh.Form This wrapper implements the dimension model * Prepare logs to live inside layout Instead of having the logs view respond to the stack size, we will put it in a layout in a future commit. This change makes it implement the DimensionModel interface * Return form fields when parsing cobra command We return fields instead of a complete form so that we can define tabs with subsets of the fields. This commit doesn't compile. The commit will fix up the logview to properly handle the tabs * Move searching and footer to logview * Fix up log test * Add log view test * Address comments * Use space instead of x * Fix form test
- Loading branch information
Showing
19 changed files
with
937 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package tui | ||
|
||
import "github.com/charmbracelet/bubbletea" | ||
|
||
// DimensionModel is an extension of tea.Model that implements a | ||
// SetWidth and SetHeight method. This allows for models to handle their | ||
// own sizing. For models that contain child models, their implementation | ||
// to SetWidth and SetHeight should also call SetWidth and SetHeight on | ||
// the child models and subtract out any padding or margins that the parent | ||
// model may have. | ||
// | ||
// This allows for a more flexible and composable layout system, where each | ||
// model is in charge of its own size and layout. | ||
type DimensionModel interface { | ||
tea.Model | ||
SetWidth(int) | ||
SetHeight(int) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package tui | ||
|
||
import ( | ||
tea "github.com/charmbracelet/bubbletea" | ||
"github.com/charmbracelet/huh" | ||
) | ||
|
||
const ( | ||
minHeight = 10 | ||
) | ||
|
||
// Form is a wrapper around a huh form that implements the layout.DimensionModel interface | ||
type Form struct { | ||
*huh.Form | ||
} | ||
|
||
func NewForm(huhForm *huh.Form) *Form { | ||
return &Form{Form: huhForm} | ||
} | ||
|
||
func (f *Form) Init() tea.Cmd { | ||
return f.Form.Init() | ||
} | ||
|
||
func (f *Form) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | ||
_, cmd := f.Form.Update(msg) | ||
return f, cmd | ||
} | ||
|
||
func (f *Form) View() string { | ||
return f.Form.View() | ||
} | ||
|
||
func (f *Form) SetWidth(width int) { | ||
f.Form = f.Form.WithWidth(width) | ||
} | ||
|
||
func (f *Form) SetHeight(height int) { | ||
// Ensure the form is at least minHeight high | ||
// otherwise it may collapse some fields (like options) | ||
// and not expand even if the height eventually exceeds | ||
// minHeight | ||
f.Form = f.Form.WithHeight(max(height, minHeight)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package layouts | ||
|
||
import ( | ||
tea "github.com/charmbracelet/bubbletea" | ||
"github.com/charmbracelet/lipgloss" | ||
"github.com/renderinc/cli/pkg/tui" | ||
) | ||
|
||
// BoxLayout is a simple layout that renders a single child model with a | ||
// specified style. It implements the DimensionModel interface so it can | ||
// be a convenient way to wrap a model with a style. | ||
type BoxLayout struct { | ||
style lipgloss.Style | ||
content tui.DimensionModel | ||
} | ||
|
||
func NewBoxLayout(style lipgloss.Style, content tui.DimensionModel) *BoxLayout { | ||
return &BoxLayout{style: style, content: content} | ||
} | ||
|
||
func (l *BoxLayout) Init() tea.Cmd { | ||
return l.content.Init() | ||
} | ||
|
||
func (l *BoxLayout) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | ||
_, cmd := l.content.Update(msg) | ||
return l, cmd | ||
} | ||
|
||
func (l *BoxLayout) View() string { | ||
return l.style.Render(l.content.View()) | ||
} | ||
|
||
func (l *BoxLayout) SetWidth(width int) { | ||
l.content.SetWidth(width - l.style.GetHorizontalFrameSize()) | ||
} | ||
|
||
func (l *BoxLayout) SetHeight(height int) { | ||
l.content.SetHeight(height - l.style.GetVerticalFrameSize()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package layouts_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/charmbracelet/lipgloss" | ||
"github.com/renderinc/cli/pkg/tui/layouts" | ||
"github.com/renderinc/cli/pkg/tui/testhelper" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestBoxLayout(t *testing.T) { | ||
t.Run("properly calculates interior width and height", func(t *testing.T) { | ||
child := testhelper.FakeDimensionModel{Value: "foo"} | ||
|
||
style := lipgloss.NewStyle().Padding(1, 2, 3, 4).Margin(1, 2, 3, 4) | ||
|
||
box := layouts.NewBoxLayout(style, &child) | ||
|
||
box.SetWidth(20) | ||
box.SetHeight(20) | ||
|
||
// The box should have right padding and margin of 2 and left padding and margin of 4 for a total of 12 | ||
require.Equal(t, 20-12, child.Width) | ||
|
||
// The box should have top padding and margin of 1 and bottom padding and margin of 3 for a total of 8 | ||
require.Equal(t, 20-8, child.Height) | ||
}) | ||
} |
Oops, something went wrong.