mirror of https://github.com/statping/statping
drag n drop ordering - UI changes - export fixed - issues fixed
parent
9682087ada
commit
889831c1de
6
Makefile
6
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.49
|
||||
VERSION=0.5
|
||||
BINARY_NAME=statup
|
||||
GOPATH:=$(GOPATH)
|
||||
GOCMD=go
|
||||
|
@ -27,7 +27,7 @@ docker-publish-all: docker-build-base docker-dev docker docker-push-base docker-
|
|||
build: compile
|
||||
$(GOBUILD) $(BUILDVERSION) -o $(BINARY_NAME) -v ./cmd
|
||||
|
||||
install: clean build
|
||||
install: build
|
||||
mv $(BINARY_NAME) $(GOPATH)/bin/$(BINARY_NAME)
|
||||
$(GOPATH)/bin/$(BINARY_NAME) version
|
||||
|
||||
|
@ -133,7 +133,7 @@ dev-deps: dep
|
|||
$(GOCMD) get github.com/mgechev/revive
|
||||
|
||||
clean:
|
||||
rm -rf ./{logs,assets,plugins,statup.db,config.yml,.sass-cache,config.yml,statup,build,.sass-cache,statup.db}
|
||||
rm -rf ./{logs,assets,plugins,statup.db,config.yml,.sass-cache,config.yml,statup,build,.sass-cache,statup.db,index.html}
|
||||
rm -rf cmd/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log}
|
||||
rm -rf core/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log}
|
||||
rm -rf handlers/{logs,assets,plugins,statup.db,config.yml,.sass-cache,*.log}
|
||||
|
|
|
@ -94,7 +94,6 @@ func CatchCLI(args []string) error {
|
|||
utils.Log(4, "config.yml file not found")
|
||||
return err
|
||||
}
|
||||
RunOnce()
|
||||
indexSource := core.ExportIndexHTML()
|
||||
err = core.SaveFile("./index.html", []byte(indexSource))
|
||||
if err != nil {
|
||||
|
|
|
@ -40,12 +40,11 @@ func TestHelpCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestExportCommand(t *testing.T) {
|
||||
t.SkipNow()
|
||||
c := testcli.Command("statup", "export")
|
||||
c.Run()
|
||||
t.Log(c.Stdout())
|
||||
assert.True(t, c.StdoutContains("Exporting Static 'index.html' page"))
|
||||
assert.True(t, fileExists(dir+"/cmd/index.html"))
|
||||
assert.True(t, fileExists(dir+"/index.html"))
|
||||
}
|
||||
|
||||
func TestAssetsCommand(t *testing.T) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -71,7 +72,13 @@ func (s *Service) duration() time.Duration {
|
|||
|
||||
func (s *Service) dnsCheck() (float64, error) {
|
||||
t1 := time.Now()
|
||||
url, err := url.Parse(s.Domain)
|
||||
domain := s.Domain
|
||||
hasPort, _ := regexp.MatchString(`\:([0-9]+)`, domain)
|
||||
if hasPort {
|
||||
splitDomain := strings.Split(s.Domain, ":")
|
||||
domain = splitDomain[len(splitDomain)-2]
|
||||
}
|
||||
url, err := url.Parse(domain)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
11
core/core.go
11
core/core.go
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -153,9 +154,17 @@ func SelectCore() (*Core, error) {
|
|||
return CoreApp, err
|
||||
}
|
||||
|
||||
type ServiceOrder []*types.Service
|
||||
|
||||
func (c ServiceOrder) Len() int { return len(c) }
|
||||
func (c ServiceOrder) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order }
|
||||
|
||||
func (c *Core) Services() []*Service {
|
||||
var services []*Service
|
||||
for _, ser := range CoreApp.GetServices() {
|
||||
servs := CoreApp.GetServices()
|
||||
sort.Sort(ServiceOrder(servs))
|
||||
for _, ser := range servs {
|
||||
services = append(services, ReturnService(ser))
|
||||
}
|
||||
return services
|
||||
|
|
|
@ -17,22 +17,33 @@ package core
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func injectDatabase() {
|
||||
DbConnection(Configs.Connection, false, utils.Directory)
|
||||
}
|
||||
|
||||
func ExportIndexHTML() string {
|
||||
source.Assets()
|
||||
injectDatabase()
|
||||
CoreApp.SelectAllServices()
|
||||
CoreApp.UseCdn = true
|
||||
//out := index{*CoreApp, CoreApp.DbServices}
|
||||
for _, service := range CoreApp.Services() {
|
||||
service = service.Check(true)
|
||||
fmt.Println(service.Name, service.Online, service.Latency)
|
||||
}
|
||||
nav, _ := source.TmplBox.String("nav.html")
|
||||
footer, _ := source.TmplBox.String("footer.html")
|
||||
render, err := source.TmplBox.String("index.html")
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
|
||||
t := template.New("message")
|
||||
t.Funcs(template.FuncMap{
|
||||
"js": func(html string) template.JS {
|
||||
|
@ -53,12 +64,38 @@ func ExportIndexHTML() string {
|
|||
"underscore": func(html string) string {
|
||||
return utils.UnderScoreString(html)
|
||||
},
|
||||
"URL": func() string {
|
||||
return "/"
|
||||
},
|
||||
"CHART_DATA": func() string {
|
||||
return ExportChartsJs()
|
||||
},
|
||||
})
|
||||
t, _ = t.Parse(nav)
|
||||
t, _ = t.Parse(footer)
|
||||
t.Parse(render)
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, nil); err != nil {
|
||||
if err := t.Execute(&tpl, CoreApp); err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
result := tpl.String()
|
||||
return result
|
||||
}
|
||||
|
||||
func ExportChartsJs() string {
|
||||
render, err := source.JsBox.String("charts.js")
|
||||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
}
|
||||
t := template.New("charts")
|
||||
t.Funcs(template.FuncMap{
|
||||
"safe": func(html string) template.HTML {
|
||||
return template.HTML(html)
|
||||
},
|
||||
})
|
||||
t.Parse(render)
|
||||
var tpl bytes.Buffer
|
||||
if err := t.Execute(&tpl, CoreApp.Services()); err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
result := tpl.String()
|
||||
|
|
|
@ -212,7 +212,6 @@ func (s *Service) index() int {
|
|||
|
||||
func updateService(service *Service) {
|
||||
service.Start()
|
||||
go service.CheckQueue(true)
|
||||
index := service.index()
|
||||
CoreApp.UpdateService(index, service.Service)
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ func (u *Service) Delete() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (u *Service) Update() error {
|
||||
func (u *Service) Update(restart bool) error {
|
||||
u.CreatedAt = time.Now()
|
||||
res := serviceCol().Find("id", u.Id)
|
||||
err := res.Update(u)
|
||||
|
@ -238,8 +237,13 @@ func (u *Service) Update() error {
|
|||
utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", u.Name, err))
|
||||
return err
|
||||
}
|
||||
u.Close()
|
||||
if restart {
|
||||
u.Close()
|
||||
}
|
||||
updateService(u)
|
||||
if restart {
|
||||
go u.CheckQueue(true)
|
||||
}
|
||||
OnUpdateService(u)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ func TestUpdateService(t *testing.T) {
|
|||
assert.True(t, service2.Online)
|
||||
service.Name = "Updated Google"
|
||||
service.Interval = 5
|
||||
err := service.Update()
|
||||
err := service.Update(true)
|
||||
assert.Nil(t, err)
|
||||
// check if updating pointer array shutdown any other service
|
||||
service2 = SelectService(2)
|
||||
|
@ -70,7 +70,7 @@ func TestUpdateAllServices(t *testing.T) {
|
|||
srv := ReturnService(s)
|
||||
srv.Name = "Changed " + srv.Name
|
||||
srv.Interval = k + 3
|
||||
err := srv.Update()
|
||||
err := srv.Update(true)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
}
|
||||
|
@ -300,3 +300,16 @@ func TestServiceCheckQueue(t *testing.T) {
|
|||
s.Close()
|
||||
assert.False(t, s.IsRunning())
|
||||
}
|
||||
|
||||
func TestDNScheckService(t *testing.T) {
|
||||
s := ReturnService(new(types.Service))
|
||||
s.Name = "example"
|
||||
s.Domain = "http://localhost:9000"
|
||||
s.Type = "http"
|
||||
s.Method = "GET"
|
||||
s.ExpectedStatus = 200
|
||||
s.Interval = 1
|
||||
amount, err := s.dnsCheck()
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, amount)
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ func ApiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
decoder := json.NewDecoder(r.Body)
|
||||
decoder.Decode(&updatedService)
|
||||
service = core.ReturnService(updatedService)
|
||||
err := service.Update()
|
||||
err := service.Update(true)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
|
@ -114,6 +114,9 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
|
|||
"URL": func() string {
|
||||
return r.URL.String()
|
||||
},
|
||||
"CHART_DATA": func() string {
|
||||
return ""
|
||||
},
|
||||
})
|
||||
t, err = t.Parse(nav)
|
||||
if err != nil {
|
||||
|
|
|
@ -57,6 +57,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/logout", http.HandlerFunc(LogoutHandler))
|
||||
r.Handle("/services", http.HandlerFunc(ServicesHandler)).Methods("GET")
|
||||
r.Handle("/services", http.HandlerFunc(CreateServiceHandler)).Methods("POST")
|
||||
r.Handle("/services/reorder", http.HandlerFunc(ReorderServiceHandler)).Methods("POST")
|
||||
r.Handle("/service/{id}", http.HandlerFunc(ServicesViewHandler)).Methods("GET")
|
||||
r.Handle("/service/{id}", http.HandlerFunc(ServicesUpdateHandler)).Methods("POST")
|
||||
r.Handle("/service/{id}/edit", http.HandlerFunc(ServicesViewHandler))
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/hunterlong/statup/core"
|
||||
|
@ -44,6 +45,27 @@ func ServicesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
ExecuteResponse(w, r, "services.html", core.CoreApp.Services())
|
||||
}
|
||||
|
||||
type serviceOrder struct {
|
||||
Id int64 `json:"service"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
func ReorderServiceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
var newOrder []*serviceOrder
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
decoder.Decode(&newOrder)
|
||||
for _, s := range newOrder {
|
||||
service := core.SelectService(s.Id)
|
||||
service.Order = s.Order
|
||||
service.Update(false)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func CreateServiceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
|
@ -150,7 +172,7 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Timeout: timeout,
|
||||
Order: order,
|
||||
})
|
||||
serviceUpdate.Update()
|
||||
serviceUpdate.Update(true)
|
||||
serviceUpdate = serviceUpdate.Check(true)
|
||||
ExecuteResponse(w, r, "service.html", serviceUpdate)
|
||||
}
|
||||
|
|
|
@ -354,6 +354,22 @@ HTML, BODY {
|
|||
box-shadow: 0 0 7px #47d337;
|
||||
animation: glow-grow 2s ease-out infinite; }
|
||||
|
||||
.sortable {
|
||||
cursor: move;
|
||||
/* fallback if grab cursor is unsupported */
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab; }
|
||||
|
||||
/* (Optional) Apply a "closed-hand" cursor during drag operation. */
|
||||
.sortable:active {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing; }
|
||||
|
||||
.sortable_drag {
|
||||
background-color: #0000000f; }
|
||||
|
||||
@media (max-width: 767px) {
|
||||
HTML, BODY {
|
||||
background-color: #fcfcfc; }
|
||||
|
@ -393,7 +409,7 @@ HTML, BODY {
|
|||
padding: 5px 5px; }
|
||||
|
||||
.lg_number {
|
||||
font-size: 1.5rem; }
|
||||
font-size: 9vw; }
|
||||
|
||||
.stats_area {
|
||||
margin-top: 1.5rem !important;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -29,7 +29,7 @@ $('form').submit(function() {
|
|||
|
||||
$('select#service_type').on('change', function() {
|
||||
var selected = $('#service_type option:selected').val();
|
||||
if (selected == "tcp") {
|
||||
if (selected === "tcp") {
|
||||
$("#service_port").parent().parent().removeClass("d-none");
|
||||
$("#service_check_type").parent().parent().addClass("d-none");
|
||||
$("#service_url").attr("placeholder", "localhost");
|
||||
|
@ -51,7 +51,7 @@ $('select#service_type').on('change', function() {
|
|||
|
||||
$('select#service_check_type').on('change', function() {
|
||||
var selected = $('#service_check_type option:selected').val();
|
||||
if (selected == "POST") {
|
||||
if (selected === "POST") {
|
||||
$("#post_data").parent().parent().removeClass("d-none");
|
||||
} else {
|
||||
$("#post_data").parent().parent().addClass("d-none");
|
||||
|
@ -61,23 +61,19 @@ $('select#service_check_type').on('change', function() {
|
|||
|
||||
$(function() {
|
||||
var pathname = window.location.pathname;
|
||||
if (pathname=="/logs") {
|
||||
if (pathname==="/logs") {
|
||||
var lastline;
|
||||
var logArea = $("#live_logs");
|
||||
setInterval(function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/logs/line');
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {
|
||||
if (lastline != xhr.responseText) {
|
||||
var curr = $.trim($("#live_logs").text());
|
||||
var line = xhr.responseText.replace(/(\r\n|\n|\r)/gm," ");
|
||||
line = line+"\n";
|
||||
$("#live_logs").text(line+curr);
|
||||
lastline = xhr.responseText;
|
||||
}
|
||||
$.get("/logs/line", function(data, status){
|
||||
if (lastline !== data) {
|
||||
var curr = $.trim(logArea.text());
|
||||
var line = data.replace(/(\r\n|\n|\r)/gm, " ");
|
||||
line = line + "\n";
|
||||
logArea.text(line + curr);
|
||||
lastline = data;
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
|
@ -102,7 +98,7 @@ var ranVar = false;
|
|||
var ranTheme = false;
|
||||
$('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
|
||||
var target = $(e.target).attr("href");
|
||||
if (target=="#v-pills-style" && !ranVar) {
|
||||
if (target==="#v-pills-style" && !ranVar) {
|
||||
var sass_vars = CodeMirror.fromTextArea(document.getElementById("sass_vars"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
|
@ -110,7 +106,7 @@ $('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
|
|||
colorpicker : true
|
||||
});
|
||||
ranVar = true;
|
||||
} else if (target=="#pills-theme" && !ranTheme) {
|
||||
} else if (target==="#pills-theme" && !ranTheme) {
|
||||
var theme_css = CodeMirror.fromTextArea(document.getElementById("theme_css"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,7 +19,6 @@ HTML,BODY {
|
|||
color: $description-color;
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
border-radius: $global-border-radius;
|
||||
}
|
||||
|
@ -411,5 +410,22 @@ HTML,BODY {
|
|||
animation: glow-grow 2s ease-out infinite;
|
||||
}
|
||||
|
||||
.sortable {
|
||||
cursor: move; /* fallback if grab cursor is unsupported */
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
}
|
||||
|
||||
/* (Optional) Apply a "closed-hand" cursor during drag operation. */
|
||||
.sortable:active {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
}
|
||||
|
||||
.sortable_drag {
|
||||
background-color: #0000000f;
|
||||
}
|
||||
|
||||
@import 'mobile';
|
|
@ -48,7 +48,7 @@
|
|||
}
|
||||
|
||||
.lg_number {
|
||||
font-size: $sm-service-stats-size;
|
||||
font-size: 9vw;
|
||||
}
|
||||
|
||||
.stats_area {
|
||||
|
|
|
@ -147,7 +147,8 @@ func CreateAllAssets(folder string) error {
|
|||
CopyToPublic(CssBox, folder+"/assets/css", "base.css")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "bootstrap.min.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "Chart.bundle.min.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "jquery-3.3.1.slim.min.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "jquery-3.3.1.min.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "sortable.min.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "main.js")
|
||||
CopyToPublic(JsBox, folder+"/assets/js", "setup.js")
|
||||
CopyToPublic(TmplBox, folder+"/assets", "robots.txt")
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
{{template "nav" }}
|
||||
|
||||
<div class="col-12 mt-5">
|
||||
<div class="col-12 mt-3">
|
||||
|
||||
<div class="row stats_area mb-5">
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
{{ range .Core.Services }}
|
||||
{{ if .LimitedFailures }}
|
||||
<h4>{{.Name}} Failures</h4>
|
||||
<h4 class="text-truncate">{{.Name}} Failures</h4>
|
||||
<div class="list-group mt-3 mb-4">
|
||||
{{ range .LimitedFailures }}
|
||||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
|
@ -84,15 +84,14 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -31,11 +31,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
|
||||
{{if USE_CDN}}
|
||||
<link rel="shortcut icon" type="image/x-icon" href="https://assets.statup.io/favicon.ico">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://assets.statup.io/base.css">
|
||||
{{ else }}
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/css/base.css">
|
||||
{{end}}
|
||||
|
@ -101,23 +102,28 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/Chart.bundle.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
<script src="/charts.js"></script>
|
||||
|
||||
{{ if .Style }}
|
||||
<style>
|
||||
{{ safe .Style }}
|
||||
</style>
|
||||
{{ end }}
|
||||
{{if CHART_DATA}}
|
||||
<script>{{ js CHART_DATA }}</script>
|
||||
{{ else }}
|
||||
<script src="/charts.js"></script>
|
||||
{{ end }}
|
||||
|
||||
{{ if .Style }}
|
||||
<style>
|
||||
{{ safe .Style }}
|
||||
</style>
|
||||
{{ end }}
|
||||
|
||||
|
||||
</body>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||
|
||||
<div class="col-8 offset-2 mt-3">
|
||||
<div class="col-10 offset-1 col-md-8 offset-md-2 mt-md-2">
|
||||
|
||||
<div class="col-md-6 col-sm-12 offset-md-3 mb-4"><img width="100%" src="/statup.png"></div>
|
||||
<div class="col-12 col-md-6 offset-md-3 mb-4"><img class="col-12 mt-5 mt-md-0" src="/statup.png"></div>
|
||||
|
||||
{{ if .Error }}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
|
@ -54,11 +54,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -264,11 +264,11 @@
|
|||
</script>
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -23,24 +23,23 @@
|
|||
|
||||
<h3>Services</h3>
|
||||
|
||||
<table class="table table-striped">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col" class="d-none d-md-table-cell">Status</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody class="sortable">
|
||||
{{range .}}
|
||||
{{ $s := . }}
|
||||
<tr draggable="true">
|
||||
<td>{{$s.Name}}</td>
|
||||
<td>{{if $s.Online}}<span class="badge badge-success">ONLINE</span>{{else}}<span class="badge badge-danger">OFFLINE</span>{{end}} </td>
|
||||
<tr id="{{.Id}}">
|
||||
<td>{{.Name}}</td>
|
||||
<td class="d-none d-md-table-cell">{{if .Online}}<span class="badge badge-success">ONLINE</span>{{else}}<span class="badge badge-danger">OFFLINE</span>{{end}} </td>
|
||||
<td class="text-right">
|
||||
<div class="btn-group">
|
||||
<a href="/service/{{$s.Id}}" class="btn btn-primary">View</a>
|
||||
<a href="/service/{{$s.Id}}/delete" class="btn btn-danger confirm-btn">Delete</a>
|
||||
<a href="/service/{{.Id}}" class="btn btn-primary">View</a>
|
||||
<a href="/service/{{.Id}}/delete" class="btn btn-danger confirm-btn">Delete</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -139,14 +138,38 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/sortable.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
||||
<script>
|
||||
sortable('.sortable', {
|
||||
forcePlaceholderSize: true,
|
||||
hoverClass: 'sortable_drag'
|
||||
});
|
||||
|
||||
sortable('.sortable')[0].addEventListener('sortupdate', function(e) {
|
||||
var i = 0;
|
||||
var newOrder = [];
|
||||
var dest = e.detail.destination.items;
|
||||
dest.forEach(function(d) {
|
||||
i++;
|
||||
var o = {service: parseInt(d.id), order: i}
|
||||
newOrder.push(o);
|
||||
});
|
||||
|
||||
$.post("/services/reorder", JSON.stringify(newOrder), function(data, status){
|
||||
console.log("Data: " + data + "\nStatus: " + status);
|
||||
});
|
||||
console.log(newOrder);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -212,10 +212,10 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
{{end}}
|
||||
|
||||
|
|
|
@ -118,11 +118,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/setup.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/setup.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
<form action="/user/{{.Id}}" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Username</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-6 col-md-4">
|
||||
<input type="text" name="username" class="form-control" value="{{.Username}}" id="username" placeholder="Username" required>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-6 col-md-4">
|
||||
<span class="switch">
|
||||
<input type="checkbox" name="admin" class="switch" id="switch-normal"{{if .Admin}} checked{{end}}>
|
||||
<label for="switch-normal">Administrator</label>
|
||||
|
@ -68,11 +68,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
|
@ -50,10 +50,10 @@
|
|||
<form action="/users" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Username</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-6 col-md-4">
|
||||
<input type="text" name="username" class="form-control" id="username" placeholder="Username" required autocapitalize="false" spellcheck="false">
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-6 col-md-4">
|
||||
<span class="switch">
|
||||
<input type="checkbox" name="admin" class="switch" id="switch-normal">
|
||||
<label for="switch-normal">Administrator</label>
|
||||
|
@ -92,11 +92,11 @@
|
|||
{{template "footer"}}
|
||||
|
||||
{{if USE_CDN}}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://assets.statup.io/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.slim.min.js"></script>
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in New Issue