Commit 694234d
Changed files (8)
internal/app/model.go
@@ -9,10 +9,10 @@ import (
)
type model struct {
- stats ufw.Stats
+ stats ufw.Stats
policy ufw.Policy
- rules []ufw.Rule
- err error
+ rules []ufw.Rule
+ err error
activeSection int
@@ -20,11 +20,9 @@ type model struct {
height int
styles ui.Styles
- statsSection stats.Model
+ statsSection stats.Model
policySection policy.Model
rulesSection rules.Model
-
- openMenu bool
}
func InitialModel() model {
@@ -39,10 +37,8 @@ func InitialModel() model {
width: 87,
height: 30,
- statsSection: stats.New(styles),
+ statsSection: stats.New(styles),
policySection: policy.New(styles),
- rulesSection: rules.New(styles),
-
- openMenu : false,
+ rulesSection: rules.New(styles),
}
}
internal/app/update.go
@@ -58,7 +58,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, sectionCmd
case sections.RulesSection:
- newRules, sectionCmd := m.rulesSection.Update(msg,m.rules)
+ newRules, sectionCmd := m.rulesSection.Update(msg, m.rules)
m.rulesSection = newRules
return m, sectionCmd
}
@@ -98,5 +98,5 @@ func (m *model) focusActiveSection() {
}
func (m *model) isMenuOpen() bool {
- return m.statsSection.GetMenu() != nil || m.rulesSection.GetMenu() != nil
+ return m.statsSection.HasOpenMenu() || m.rulesSection.HasOpenMenu()
}
internal/app/view.go
@@ -7,6 +7,15 @@ import (
"github.com/charmbracelet/lipgloss"
)
+func (m model) renderCenteredOverlay(overlay, background string) string {
+ dimmed := "\x1b[2m" + lipgloss.NewStyle().Faint(true).Render(background) + "\x1b[0m"
+ overlayW := lipgloss.Width(overlay)
+ overlayH := lipgloss.Height(overlay)
+ x := (m.width - overlayW) / 2
+ y := (m.height - overlayH) / 2
+ return PlaceOverlay(x, y, overlay, dimmed)
+}
+
func (m model) View() string {
const minWidth, minHeight = 87, 30
const containerWidth, containerHeight = minWidth - 5, minHeight - 3
@@ -81,25 +90,20 @@ func (m model) View() string {
layout,
)
- var menuOpen *ui.Menu
-
- if m.statsSection.GetMenu() != nil {
- menuOpen = m.statsSection.GetMenu()
- } else if m.rulesSection.GetMenu() != nil {
- menuOpen = m.rulesSection.GetMenu()
+ if m.rulesSection.ShowingDeleteConfirm() {
+ return m.renderCenteredOverlay(m.rulesSection.DeleteConfirmView(), layout)
}
- if menuOpen != nil {
-
- dimmed := "\x1b[2m" + lipgloss.NewStyle().Faint(true).Render(layout) + "\x1b[0m"
- menuView := menuOpen.View(m.styles)
+ if m.rulesSection.ShowingDetails() {
+ return m.renderCenteredOverlay(m.rulesSection.DetailView(), layout)
+ }
- menuW := lipgloss.Width(menuView)
- menuH := lipgloss.Height(menuView)
- x := (m.width - menuW) / 2
- y := (m.height - menuH) / 2
+ if menu := m.statsSection.GetMenu(); menu != nil {
+ return m.renderCenteredOverlay(menu.View(m.styles), layout)
+ }
- return PlaceOverlay(x, y, menuView, dimmed)
+ if menu := m.rulesSection.GetMenu(); menu != nil {
+ return m.renderCenteredOverlay(menu.View(m.styles), layout)
}
return layout
internal/keys/keys.go
@@ -14,6 +14,8 @@ type KeyMap struct {
CursorUp key.Binding
CursorDown key.Binding
Execute key.Binding
+ Info key.Binding
+ Delete key.Binding
}
var Bindings = KeyMap{
@@ -44,6 +46,14 @@ var Bindings = KeyMap{
Execute: key.NewBinding(
key.WithKeys(" ", "enter"),
),
+
+ Info: key.NewBinding(
+ key.WithKeys("i"),
+ ),
+
+ Delete: key.NewBinding(
+ key.WithKeys("d"),
+ ),
}
type RefreshMsg struct{}
internal/sections/policy/model.go
@@ -7,8 +7,7 @@ import (
type Model struct {
styles ui.Styles
totalOpts int
- cursorLine int
- showMenu bool
+ cursorLine int
menu *ui.Menu
active bool
}
@@ -17,7 +16,6 @@ func New(styles ui.Styles) Model {
return Model{
styles: styles,
cursorLine: 0,
- showMenu: false,
menu: nil,
active: false,
totalOpts: 2,
@@ -31,7 +29,7 @@ func (m *Model) Focus() {
func (m *Model) Blur() {
m.active = false
- m.showMenu = false
+ m.menu = nil
m.cursorLine = 0
}
internal/sections/policy/update.go
@@ -29,7 +29,8 @@ func (m Model) Update(msg tea.Msg, policy ufw.Policy) (Model, tea.Cmd) {
case 2:
ufw.DefaultRouted(!(policy.DefaultRouted == "ALLOW"))
}
+ return m, keys.Refresh()
}
}
- return m, keys.Refresh()
+ return m, nil
}
internal/sections/stats/model.go
@@ -7,8 +7,7 @@ import (
type Model struct {
styles ui.Styles
totalOpts int
- cursorLine int
- showMenu bool
+ cursorLine int
menu *ui.Menu
active bool
}
@@ -17,7 +16,6 @@ func New(styles ui.Styles) Model {
return Model{
styles: styles,
cursorLine: 0,
- showMenu: false,
menu: nil,
active: true,
totalOpts: 2,
@@ -31,7 +29,7 @@ func (m *Model) Focus() {
func (m *Model) Blur() {
m.active = false
- m.showMenu = false
+ m.menu = nil
m.cursorLine = 0
}
internal/sections/sections.go
@@ -5,3 +5,12 @@ const (
PolicySection
RulesSection
)
+
+// All section models implement the following common methods:
+// - Focus() - activates the section and resets cursor position
+// - Blur() - deactivates the section and clears overlays/menus
+// - HasOpenMenu() - returns true if a menu overlay is displayed
+// - GetMenu() - returns the current menu or nil
+//
+// Note: Update() and View() have different signatures per section
+// because they depend on different data (stats, policy, or rules).