add basic UI
This commit is contained in:
parent
48094464eb
commit
4698e52dca
@ -15,6 +15,7 @@ import (
|
||||
|
||||
type runCmd struct {
|
||||
Directory string `long:"directory" short:"d" env:"DIRECTORY" description:"Data directory" default:"run"`
|
||||
UI string `long:"ui" env:"UI" description:"Path to UI directory" default:"templates"`
|
||||
Interval time.Duration `long:"interval" short:"i" env:"INTERVAL" description:"Requeue interval" default:"3s"`
|
||||
Attempts int `long:"attempts" short:"a" env:"ATTEMPTS" description:"Max number of attempts" default:"5"`
|
||||
Concurrency int `long:"concurrency" short:"c" env:"CONCURRENCY" description:"Number of parallel worker (0 - mean number of CPU)" default:"0"`
|
||||
@ -35,6 +36,7 @@ func (cfg *runCmd) Execute([]string) error {
|
||||
srv := runner.DefaultConfig()
|
||||
srv.Bind = cfg.Bind
|
||||
srv.WorkingDirectory = cfg.Directory
|
||||
srv.UIDirectory = cfg.UI
|
||||
srv.ConfigDirectory = tmpDir
|
||||
|
||||
unit := server.DefaultUnit()
|
||||
|
@ -91,14 +91,13 @@ func (cfg Config) Create(global context.Context) (*Server, error) {
|
||||
ctx, cancel := context.WithCancel(global)
|
||||
|
||||
router := gin.Default()
|
||||
router.LoadHTMLGlob(filepath.Join(cfg.UIDirectory, "*.html"))
|
||||
router.Static("/static", filepath.Join(cfg.UIDirectory, "static"))
|
||||
server.Attach(router.Group("/api/"), units, workers)
|
||||
ui.Attach(router.Group("/ui/"), units, cfg.UIDirectory)
|
||||
router.Group("/", func(gctx *gin.Context) {
|
||||
ui.Attach(router.Group("/ui/"), units)
|
||||
router.GET("/", func(gctx *gin.Context) {
|
||||
gctx.Redirect(http.StatusTemporaryRedirect, "ui")
|
||||
})
|
||||
//router.Path("/").Methods("GET").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
// http.Redirect(writer, request, "ui", http.StatusTemporaryRedirect)
|
||||
//})
|
||||
|
||||
srv := &Server{
|
||||
Handler: router,
|
||||
|
@ -1,11 +1,9 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Masterminds/sprig"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"nano-run/server"
|
||||
@ -13,21 +11,23 @@ import (
|
||||
|
||||
func Expose(units []server.Unit, uiDir string) http.Handler {
|
||||
router := gin.New()
|
||||
Attach(router, units, uiDir)
|
||||
router.LoadHTMLGlob(filepath.Join(uiDir, "*.html"))
|
||||
Attach(router, units)
|
||||
return router
|
||||
}
|
||||
|
||||
func Attach(router gin.IRouter, units []server.Unit, uiDir string) {
|
||||
func Attach(router gin.IRouter, units []server.Unit) {
|
||||
ui := &uiRouter{
|
||||
dir: uiDir,
|
||||
units: units,
|
||||
}
|
||||
router.GET("", func(gctx *gin.Context) {
|
||||
gctx.Redirect(http.StatusTemporaryRedirect, "units")
|
||||
})
|
||||
router.GET("/units", ui.listUnits)
|
||||
router.GET("/unit/:name", ui.unitInfo)
|
||||
}
|
||||
|
||||
type uiRouter struct {
|
||||
dir string
|
||||
units []server.Unit
|
||||
}
|
||||
|
||||
@ -58,15 +58,3 @@ func (ui *uiRouter) listUnits(gctx *gin.Context) {
|
||||
reply.Units = ui.units
|
||||
gctx.HTML(http.StatusOK, "units-list.html", reply)
|
||||
}
|
||||
|
||||
func (ui *uiRouter) getTemplate(name string) *template.Template {
|
||||
t, err := template.New("").Funcs(sprig.HtmlFuncMap()).ParseFiles(filepath.Join(ui.dir, name))
|
||||
if err == nil {
|
||||
return t
|
||||
}
|
||||
t, err = template.New("").Parse("<html><body>Ooops... Page not found</body></html>")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
@ -1,18 +1,106 @@
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="https://unpkg.com/mvp.css">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<a href="unit/{{.Unit.Name}}">
|
||||
<h2>{{.Unit.Name}}</h2>
|
||||
{{if .Unit.Secured}}
|
||||
secured
|
||||
<main>
|
||||
<section>
|
||||
<header>
|
||||
<h2><a href="../units">Units</a> :: {{.Unit.Name}}</h2>
|
||||
<h4>
|
||||
<code><script>document.write((new URL("../../api/{{.Unit.Name}}/", window.location).href))</script></code>
|
||||
</h4>
|
||||
</header>
|
||||
<aside>
|
||||
<h3>Configuration</h3>
|
||||
<ul>
|
||||
{{with .Unit}}
|
||||
<li>
|
||||
<b>Mode: </b>{{.Mode}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Concurrency: </b>{{.Workers}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Attempts: </b>{{.Attempts}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Interval: </b>{{.Interval}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Timeout: </b>
|
||||
{{with .Timeout}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
∞
|
||||
{{end}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Max request size: </b>
|
||||
{{with .MaxRequest}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
∞
|
||||
{{end}}
|
||||
</li>
|
||||
<li>
|
||||
<b>Working directory: </b>
|
||||
{{with .WorkDir}}
|
||||
<sup>static</sup>
|
||||
<span style="overflow-x: auto; word-break: break-all">{{.}}</span>
|
||||
{{else}}
|
||||
<i>dynamic</i>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</aside>
|
||||
<aside>
|
||||
<h3>Environment</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $k,$v := .Unit.Environment}}
|
||||
<tr>
|
||||
<td>
|
||||
<pre>{{$k}}</pre>
|
||||
</td>
|
||||
<td>{{$v}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</aside>
|
||||
{{with .Unit.Authorization}}
|
||||
<aside>
|
||||
<h3>Authorization{{if not $.Unit.Secured}} ⚠️{{end}}</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th>JWT</th>
|
||||
<td>{{if .JWT.Enable}}✅{{else}}❌{{end}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Token in query</th>
|
||||
<td>{{if .QueryToken.Enable}}✅{{else}}❌{{end}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Token in header</th>
|
||||
<td>{{if .HeaderToken.Enable}}✅{{else}}❌{{end}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Basic auth</th>
|
||||
<td>{{if .Basic.Enable}}✅{{else}}❌{{end}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</aside>
|
||||
{{end}}
|
||||
</a>
|
||||
<p>
|
||||
<span class="unit-mode unit-mode-{{.Unit.Mode}}">{{.Unit.Mode}}</span>,
|
||||
<span class="unit-mode unit-mode-workers">{{.Unit.Workers}}</span>,
|
||||
<span class="unit-mode unit-mode-interval">{{.Unit.Interval}}</span>,
|
||||
<span class="unit-mode unit-mode-timeout">{{.Unit.Timeout}}</span>,
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -1,17 +1,78 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="https://unpkg.com/mvp.css">
|
||||
</head>
|
||||
<body>
|
||||
{{range .Units}}
|
||||
<div>
|
||||
<a href="unit/{{.Name}}">
|
||||
<h2>{{.Name}}</h2>
|
||||
</a>
|
||||
<p>
|
||||
<span class="unit-mode unit-mode-{{.Mode}}">{{.Mode}}</span>,
|
||||
<span class="unit-mode unit-mode-workers">{{.Workers}}</span>,
|
||||
<span class="unit-mode unit-mode-interval">{{.Interval}}</span>,
|
||||
<span class="unit-mode unit-mode-timeout">{{.Timeout}}</span>,
|
||||
</p>
|
||||
</div>
|
||||
{{end}}
|
||||
<header>
|
||||
<nav>
|
||||
</nav>
|
||||
<h1> Units </h1>
|
||||
</header>
|
||||
<main>
|
||||
<section>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Mode</th>
|
||||
<th>Concurrency</th>
|
||||
<th>Attempts</th>
|
||||
<th>Interval</th>
|
||||
<th>Timeout</th>
|
||||
<th>Max request size</th>
|
||||
<th>Working directory</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Units}}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="unit/{{.Name}}">
|
||||
{{.Name}}{{if .Secured}} (secured){{end}}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="unit-mode unit-mode-{{.Mode}}">{{.Mode}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="unit-mode unit-mode-workers">{{.Workers}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{.Attempts}}
|
||||
</td>
|
||||
<td>
|
||||
<span class="unit-mode unit-mode-interval">{{.Interval}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{with .Timeout}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
∞
|
||||
{{end}}
|
||||
</td>
|
||||
<td>
|
||||
{{with .MaxRequest}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
∞
|
||||
{{end}}
|
||||
</td>
|
||||
<td>
|
||||
{{with .WorkDir}}
|
||||
<details>
|
||||
<summary>static</summary>
|
||||
<p>{{.}}</p>
|
||||
</details>
|
||||
{{else}}
|
||||
<i>dynamic</i>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user