textbox component

This commit is contained in:
sqshq 2019-04-09 22:30:21 -04:00
parent 4206a8cbf7
commit b542e0bd0c
6 changed files with 144 additions and 25 deletions

View File

@ -0,0 +1,62 @@
package textbox
import (
ui "github.com/gizak/termui/v3"
"github.com/sqshq/sampler/component"
"github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data"
"image"
)
type TextBox struct {
*ui.Block
*data.Consumer
alert *data.Alert
text string
border bool
}
func NewTextBox(c config.TextBoxConfig, palette console.Palette) *TextBox {
box := TextBox{
Block: component.NewBlock(c.Title, *c.Border, palette),
Consumer: data.NewConsumer(),
}
go func() {
for {
select {
case sample := <-box.SampleChannel:
box.text = sample.Value
case alert := <-box.AlertChannel:
box.alert = alert
}
}
}()
return &box
}
func (t *TextBox) Draw(buffer *ui.Buffer) {
t.Block.Draw(buffer)
cells := ui.ParseStyles(t.text, ui.Theme.Paragraph.Text)
cells = ui.WrapCells(cells, uint(t.Inner.Dx()))
rows := ui.SplitCells(cells, '\n')
for y, row := range rows {
if y+t.Inner.Min.Y >= t.Inner.Max.Y {
break
}
row = ui.TrimCells(row, t.Inner.Dx())
for _, cx := range ui.BuildCellWithXArray(row) {
x, cell := cx.X, cx.Cell
buffer.SetCell(cell, image.Pt(x, y+1).Add(t.Inner.Min))
}
}
component.RenderAlert(t.alert, t.Rectangle, buffer)
}

View File

@ -27,30 +27,30 @@ runcharts:
scale: 0 scale: 0
items: items:
- label: ACTIVE - label: ACTIVE
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
- label: INACTIVE - label: INACTIVE
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
barcharts: barcharts:
- title: EVENTS BY STATUS - title: EVENTS BY STATUS
position: [[0, 17], [27, 12]] position: [[0, 17], [28, 12]]
rate-ms: 300 rate-ms: 300
scale: 0 scale: 0
items: items:
- label: NEW - label: NEW
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
- label: TRIGGERED - label: TRIGGERED
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
- label: IN_PROCESS - label: IN_PROCESS
sample: echo 0 sample: echo 0
- label: FAILED - label: FAILED
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
- label: FINISHED - label: FINISHED
init: ${mongoconnection} init: $mongoconnection
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount() sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
gauges: gauges:
- title: YEAR PROGRESS - title: YEAR PROGRESS
@ -91,6 +91,31 @@ gauges:
sample: echo 60 sample: echo 60
min: min:
sample: echo 0 sample: echo 0
sparklines:
- title: CPU usage
position: [[28, 22], [24, 7]]
scale: 0
sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
- title: Memory pages free
position: [[28, 17], [24, 5]]
scale: 0
sample: memory_pressure | grep 'Pages free' | awk '{print $3}'
textboxes:
- title: Local weather
position: [[0, 30], [13, 7]]
rate-ms: 10000
sample: curl wttr.in?0ATQF
border: false
- title: New York weather
position: [[8, 30], [13, 7]]
rate-ms: 10000
sample: curl wttr.in/newyork?0ATQF
border: false
- title: San Francisco weather
position: [[17, 30], [13, 7]]
rate-ms: 10000
sample: curl wttr.in/sanfrancisco?0ATQF
border: false
asciiboxes: asciiboxes:
- title: LOCAL TIME - title: LOCAL TIME
position: [[53, 17], [27, 5]] position: [[53, 17], [27, 5]]
@ -99,12 +124,3 @@ asciiboxes:
position: [[53, 22], [27, 7]] position: [[53, 22], [27, 7]]
sample: env TZ=UTC date +%r sample: env TZ=UTC date +%r
font: 3d font: 3d
sparklines:
- title: CPU usage
position: [[27, 22], [25, 7]]
scale: 0
sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
- title: Memory pages free
position: [[27, 17], [25, 5]]
scale: 0
sample: memory_pressure | grep 'Pages free' | awk '{print $3}'

View File

@ -70,9 +70,16 @@ type BarChartConfig struct {
type AsciiBoxConfig struct { type AsciiBoxConfig struct {
ComponentConfig `yaml:",inline"` ComponentConfig `yaml:",inline"`
Item `yaml:",inline"` Item `yaml:",inline"`
Border *bool `yaml:"border,omitempty"`
Font *console.AsciiFont `yaml:"font,omitempty"` Font *console.AsciiFont `yaml:"font,omitempty"`
} }
type TextBoxConfig struct {
ComponentConfig `yaml:",inline"`
Item `yaml:",inline"`
Border *bool `yaml:"border,omitempty"`
}
type RunChartConfig struct { type RunChartConfig struct {
ComponentConfig `yaml:",inline"` ComponentConfig `yaml:",inline"`
Legend *LegendConfig `yaml:"legend,omitempty"` Legend *LegendConfig `yaml:"legend,omitempty"`

View File

@ -16,8 +16,9 @@ type Config struct {
RunCharts []RunChartConfig `yaml:"runcharts,omitempty"` RunCharts []RunChartConfig `yaml:"runcharts,omitempty"`
BarCharts []BarChartConfig `yaml:"barcharts,omitempty"` BarCharts []BarChartConfig `yaml:"barcharts,omitempty"`
Gauges []GaugeConfig `yaml:"gauges,omitempty"` Gauges []GaugeConfig `yaml:"gauges,omitempty"`
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
SparkLines []SparkLineConfig `yaml:"sparklines,omitempty"` SparkLines []SparkLineConfig `yaml:"sparklines,omitempty"`
TextBoxes []TextBoxConfig `yaml:"textboxes,omitempty"`
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
} }
func Load() (Config, Options) { func Load() (Config, Options) {
@ -66,16 +67,22 @@ func (c *Config) findComponent(componentType ComponentType, componentTitle strin
return &c.Gauges[i].ComponentConfig return &c.Gauges[i].ComponentConfig
} }
} }
case TypeSparkLine:
for i, component := range c.SparkLines {
if component.Title == componentTitle {
return &c.SparkLines[i].ComponentConfig
}
}
case TypeAsciiBox: case TypeAsciiBox:
for i, component := range c.AsciiBoxes { for i, component := range c.AsciiBoxes {
if component.Title == componentTitle { if component.Title == componentTitle {
return &c.AsciiBoxes[i].ComponentConfig return &c.AsciiBoxes[i].ComponentConfig
} }
} }
case TypeSparkLine: case TypeTextBox:
for i, component := range c.SparkLines { for i, component := range c.TextBoxes {
if component.Title == componentTitle { if component.Title == componentTitle {
return &c.SparkLines[i].ComponentConfig return &c.TextBoxes[i].ComponentConfig
} }
} }
} }

View File

@ -120,6 +120,27 @@ func (c *Config) setDefaultValues() {
} }
c.AsciiBoxes[i] = box c.AsciiBoxes[i] = box
} }
for i, box := range c.TextBoxes {
setDefaultTriggersValues(box.Triggers)
box.ComponentConfig.Type = TypeTextBox
if box.RateMs == nil {
r := defaultRateMs
box.RateMs = &r
}
if box.Label == nil {
label := string(i)
box.Label = &label
}
if box.Border == nil {
border := true
box.Border = &border
}
c.TextBoxes[i] = box
}
} }
func setDefaultTriggersValues(triggers []TriggerConfig) { func setDefaultTriggersValues(triggers []TriggerConfig) {

16
main.go
View File

@ -10,6 +10,7 @@ import (
"github.com/sqshq/sampler/component/layout" "github.com/sqshq/sampler/component/layout"
"github.com/sqshq/sampler/component/runchart" "github.com/sqshq/sampler/component/runchart"
"github.com/sqshq/sampler/component/sparkline" "github.com/sqshq/sampler/component/sparkline"
"github.com/sqshq/sampler/component/textbox"
"github.com/sqshq/sampler/config" "github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data" "github.com/sqshq/sampler/data"
@ -58,11 +59,6 @@ func main() {
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers) starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
} }
for _, c := range cfg.AsciiBoxes {
cpt := asciibox.NewAsciiBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.BarCharts { for _, c := range cfg.BarCharts {
cpt := barchart.NewBarChart(c, palette) cpt := barchart.NewBarChart(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers) starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
@ -73,6 +69,16 @@ func main() {
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Cur, c.Min, c.Max}, c.Triggers) starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Cur, c.Min, c.Max}, c.Triggers)
} }
for _, c := range cfg.AsciiBoxes {
cpt := asciibox.NewAsciiBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.TextBoxes {
cpt := textbox.NewTextBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
handler := event.NewHandler(lout, opt) handler := event.NewHandler(lout, opt)
handler.HandleEvents() handler.HandleEvents()
} }