Skip to content

Commit

Permalink
refactor: pages, components and templates
Browse files Browse the repository at this point in the history
  • Loading branch information
jim380 committed Oct 1, 2023
1 parent a7bd123 commit b1626b4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 78 deletions.
58 changes: 58 additions & 0 deletions dashboard/components/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package components

import (
"encoding/json"
"log"

"github.com/jim380/Cendermint/rest"
"github.com/kyoto-framework/kyoto/v2"
"go.uber.org/zap"
)

/*
Component
- Each component is a context receiver, which returns its state
- Each component becomes a part of the page or top-level component,
which executes component asynchronously and gets a state future object
- Context holds common objects like http.ResponseWriter, *http.Request, etc
*/
func GetBlockInfo(ctx *kyoto.Context) (state rest.Blocks) {
route := "/cosmos/base/tendermint/v1beta1/blocks/latest" //TO-DO refactor this
fetchBlockInfo := func() rest.Blocks {
var state rest.Blocks
resp, err := rest.HttpQuery(rest.RESTAddr + route)
if err != nil {
zap.L().Fatal("Connection to REST failed", zap.Bool("Success", false), zap.String("err:", err.Error()))
return rest.Blocks{}
}

err = json.Unmarshal(resp, &state)
if err != nil {
zap.L().Fatal("Failed to unmarshal response", zap.Bool("Success", false), zap.String("err:", err.Error()))
return rest.Blocks{}
}

return state
}

/*
Handle Actions
- To call an action of parent component, use $ prefix in action name
- To call an action of component by id, use <id:action> as an action name
- To push multiple component UI updates during a single action call,
call kyoto.ActionFlush(ctx, state) to initiate an update
*/
handled := kyoto.Action(ctx, "Reload Block", func(args ...any) {
// add logic here
state = fetchBlockInfo()
log.Println("New block info fetched on block", state.Block.Header.Height)
})
// Prevent further execution if action handled
if handled {
return
}
// Default loading behavior if not handled
state = fetchBlockInfo()

return
}
21 changes: 21 additions & 0 deletions dashboard/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dashboard

import (
"os"

"github.com/jim380/Cendermint/dashboard/components"
"github.com/jim380/Cendermint/dashboard/pages"
"github.com/kyoto-framework/kyoto/v2"
)

func StartDashboard() {
go func() {
port := os.Getenv("DASHBOARD_PORT")
// Register page
kyoto.HandlePage("/", pages.PIndex)
// Client
kyoto.HandleAction(components.GetBlockInfo)
// Serve
kyoto.Serve(":" + port)
}()
}
26 changes: 26 additions & 0 deletions dashboard/pages/index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pages

import (
"github.com/jim380/Cendermint/dashboard/components"
"github.com/jim380/Cendermint/rest"
"github.com/kyoto-framework/kyoto/v2"
)

type PIndexState struct {
Block *kyoto.ComponentF[rest.Blocks]
}

/*
Page
- A page is a top-level component, which attaches components and
defines rendering
*/
func PIndex(ctx *kyoto.Context) (state PIndexState) {
// Define rendering
kyoto.Template(ctx, "page.index.html")

// Attach components
state.Block = kyoto.Use(ctx, components.GetBlockInfo)

return
}
80 changes: 2 additions & 78 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ limitations under the License.
package main

import (
"encoding/json"
"fmt"
"log"
"os"
"strings"

"github.com/jim380/Cendermint/config"
"github.com/jim380/Cendermint/dashboard"
"github.com/jim380/Cendermint/exporter"
"github.com/jim380/Cendermint/logging"
"github.com/jim380/Cendermint/rest"
"github.com/joho/godotenv"
"github.com/kyoto-framework/kyoto/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
Expand All @@ -38,73 +37,6 @@ var (
logger *zap.Logger
)

type PIndexState struct {
Block *kyoto.ComponentF[rest.Blocks]
}

/*
Page
- A page is a top-level component, which attaches components and
defines rendering
*/
func PIndex(ctx *kyoto.Context) (state PIndexState) {
// Define rendering
kyoto.Template(ctx, "page.index.html")

// Attach components
state.Block = kyoto.Use(ctx, GetBlockInfo)

return
}

/*
Component
- Each component is a context receiver, which returns its state
- Each component becomes a part of the page or top-level component,
which executes component asynchronously and gets a state future object
- Context holds common objects like http.ResponseWriter, *http.Request, etc
*/
func GetBlockInfo(ctx *kyoto.Context) (state rest.Blocks) {
route := "/cosmos/base/tendermint/v1beta1/blocks/latest" //TO-DO refactor this
fetchBlockInfo := func() rest.Blocks {
var state rest.Blocks
resp, err := rest.HttpQuery(rest.RESTAddr + route)
if err != nil {
zap.L().Fatal("Connection to REST failed", zap.Bool("Success", false), zap.String("err:", err.Error()))
return rest.Blocks{}
}

err = json.Unmarshal(resp, &state)
if err != nil {
zap.L().Fatal("Failed to unmarshal response", zap.Bool("Success", false), zap.String("err:", err.Error()))
return rest.Blocks{}
}

return state
}

/*
Handle Actions
- To call an action of parent component, use $ prefix in action name
- To call an action of component by id, use <id:action> as an action name
- To push multiple component UI updates during a single action call,
call kyoto.ActionFlush(ctx, state) to initiate an update
*/
handled := kyoto.Action(ctx, "Reload Block", func(args ...any) {
// add logic here
state = fetchBlockInfo()
log.Println("New block info fetched on block", state.Block.Header.Height)
})
// Prevent further execution if action handled
if handled {
return
}
// Default loading behavior if not handled
state = fetchBlockInfo()

return
}

func main() {
err := godotenv.Load("config.env")
if err != nil {
Expand Down Expand Up @@ -163,15 +95,7 @@ func main() {

// run dashboard in a separate thread in enabled
if strings.ToLower(cfg.DashboardEnabled) == "true" {
go func() {
port := os.Getenv("DASHBOARD_PORT")
// Register page
kyoto.HandlePage("/", PIndex)
// Client
kyoto.HandleAction(GetBlockInfo)
// Serve
kyoto.Serve(":" + port)
}()
dashboard.StartDashboard()
}

exporter.Start(&cfg, listeningPort, logger)
Expand Down

0 comments on commit b1626b4

Please sign in to comment.