textbox component
This commit is contained in:
parent
4206a8cbf7
commit
b542e0bd0c
|
@ -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)
|
||||
}
|
48
config.yml
48
config.yml
|
@ -27,30 +27,30 @@ runcharts:
|
|||
scale: 0
|
||||
items:
|
||||
- label: ACTIVE
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
|
||||
- label: INACTIVE
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
|
||||
barcharts:
|
||||
- title: EVENTS BY STATUS
|
||||
position: [[0, 17], [27, 12]]
|
||||
position: [[0, 17], [28, 12]]
|
||||
rate-ms: 300
|
||||
scale: 0
|
||||
items:
|
||||
- label: NEW
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
|
||||
- label: TRIGGERED
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
|
||||
- label: IN_PROCESS
|
||||
sample: echo 0
|
||||
- label: FAILED
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'ACTIVE'}).itcount()
|
||||
- label: FINISHED
|
||||
init: ${mongoconnection}
|
||||
init: $mongoconnection
|
||||
sample: db.getCollection('posts').find({status:'INACTIVE'}).itcount()
|
||||
gauges:
|
||||
- title: YEAR PROGRESS
|
||||
|
@ -91,6 +91,31 @@ gauges:
|
|||
sample: echo 60
|
||||
min:
|
||||
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:
|
||||
- title: LOCAL TIME
|
||||
position: [[53, 17], [27, 5]]
|
||||
|
@ -99,12 +124,3 @@ asciiboxes:
|
|||
position: [[53, 22], [27, 7]]
|
||||
sample: env TZ=UTC date +%r
|
||||
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}'
|
||||
|
|
|
@ -70,9 +70,16 @@ type BarChartConfig struct {
|
|||
type AsciiBoxConfig struct {
|
||||
ComponentConfig `yaml:",inline"`
|
||||
Item `yaml:",inline"`
|
||||
Border *bool `yaml:"border,omitempty"`
|
||||
Font *console.AsciiFont `yaml:"font,omitempty"`
|
||||
}
|
||||
|
||||
type TextBoxConfig struct {
|
||||
ComponentConfig `yaml:",inline"`
|
||||
Item `yaml:",inline"`
|
||||
Border *bool `yaml:"border,omitempty"`
|
||||
}
|
||||
|
||||
type RunChartConfig struct {
|
||||
ComponentConfig `yaml:",inline"`
|
||||
Legend *LegendConfig `yaml:"legend,omitempty"`
|
||||
|
|
|
@ -16,8 +16,9 @@ type Config struct {
|
|||
RunCharts []RunChartConfig `yaml:"runcharts,omitempty"`
|
||||
BarCharts []BarChartConfig `yaml:"barcharts,omitempty"`
|
||||
Gauges []GaugeConfig `yaml:"gauges,omitempty"`
|
||||
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
|
||||
SparkLines []SparkLineConfig `yaml:"sparklines,omitempty"`
|
||||
TextBoxes []TextBoxConfig `yaml:"textboxes,omitempty"`
|
||||
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
|
||||
}
|
||||
|
||||
func Load() (Config, Options) {
|
||||
|
@ -66,16 +67,22 @@ func (c *Config) findComponent(componentType ComponentType, componentTitle strin
|
|||
return &c.Gauges[i].ComponentConfig
|
||||
}
|
||||
}
|
||||
case TypeSparkLine:
|
||||
for i, component := range c.SparkLines {
|
||||
if component.Title == componentTitle {
|
||||
return &c.SparkLines[i].ComponentConfig
|
||||
}
|
||||
}
|
||||
case TypeAsciiBox:
|
||||
for i, component := range c.AsciiBoxes {
|
||||
if component.Title == componentTitle {
|
||||
return &c.AsciiBoxes[i].ComponentConfig
|
||||
}
|
||||
}
|
||||
case TypeSparkLine:
|
||||
for i, component := range c.SparkLines {
|
||||
case TypeTextBox:
|
||||
for i, component := range c.TextBoxes {
|
||||
if component.Title == componentTitle {
|
||||
return &c.SparkLines[i].ComponentConfig
|
||||
return &c.TextBoxes[i].ComponentConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,27 @@ func (c *Config) setDefaultValues() {
|
|||
}
|
||||
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) {
|
||||
|
|
16
main.go
16
main.go
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/sqshq/sampler/component/layout"
|
||||
"github.com/sqshq/sampler/component/runchart"
|
||||
"github.com/sqshq/sampler/component/sparkline"
|
||||
"github.com/sqshq/sampler/component/textbox"
|
||||
"github.com/sqshq/sampler/config"
|
||||
"github.com/sqshq/sampler/console"
|
||||
"github.com/sqshq/sampler/data"
|
||||
|
@ -58,11 +59,6 @@ func main() {
|
|||
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 {
|
||||
cpt := barchart.NewBarChart(c, palette)
|
||||
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)
|
||||
}
|
||||
|
||||
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.HandleEvents()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue