mirror of https://github.com/statping/statping
setting up for basePath
parent
8fe8b7e0b4
commit
479763f186
|
@ -274,6 +274,7 @@ func HelpEcho() {
|
|||
fmt.Println(" HTTP_PROXY - Use a HTTP Proxy for HTTP Requests")
|
||||
fmt.Println(" AUTH_USERNAME - HTTP Basic Authentication username")
|
||||
fmt.Println(" AUTH_PASSWORD - HTTP Basic Authentication password")
|
||||
fmt.Println(" BASE_PATH - Set the base URL prefix (set to 'monitor' if URL is domain.com/monitor)")
|
||||
fmt.Println(" * You can insert environment variables into a '.env' file in root directory.")
|
||||
fmt.Println("Give Statping a Star at https://github.com/hunterlong/statping")
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
basePath = "/"
|
||||
)
|
||||
|
||||
var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"js": func(html interface{}) template.JS {
|
||||
|
@ -88,7 +92,7 @@ var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap
|
|||
return utils.UnderScoreString(html)
|
||||
},
|
||||
"URL": func() string {
|
||||
return r.URL.String()
|
||||
return basePath + r.URL.String()
|
||||
},
|
||||
"CHART_DATA": func() string {
|
||||
return ""
|
||||
|
@ -145,5 +149,8 @@ var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap
|
|||
"NewGroup": func() *types.Group {
|
||||
return new(types.Group)
|
||||
},
|
||||
"BasePath": func() string {
|
||||
return basePath
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,13 +45,16 @@ var (
|
|||
mainTmpl = `{{define "main" }} {{ template "base" . }} {{ end }}`
|
||||
templates = []string{"base.gohtml", "head.gohtml", "nav.gohtml", "footer.gohtml", "scripts.gohtml", "form_service.gohtml", "form_notifier.gohtml", "form_integration.gohtml", "form_group.gohtml", "form_user.gohtml", "form_checkin.gohtml", "form_message.gohtml"}
|
||||
javascripts = []string{"charts.js", "chart_index.js"}
|
||||
mainTemplate *template.Template
|
||||
)
|
||||
|
||||
// RunHTTPServer will start a HTTP server on a specific IP and port
|
||||
func RunHTTPServer(ip string, port int) error {
|
||||
host := fmt.Sprintf("%v:%v", ip, port)
|
||||
|
||||
if os.Getenv("BASE_PATH") != "" {
|
||||
basePath = "/" + os.Getenv("BASE_PATH")
|
||||
}
|
||||
|
||||
key := utils.FileExists(utils.Directory + "/server.key")
|
||||
cert := utils.FileExists(utils.Directory + "/server.crt")
|
||||
|
||||
|
@ -184,22 +187,22 @@ func IsUser(r *http.Request) bool {
|
|||
return session.Values["authenticated"].(bool)
|
||||
}
|
||||
|
||||
func loadTemplate(w http.ResponseWriter, r *http.Request) error {
|
||||
func loadTemplate(w http.ResponseWriter, r *http.Request) (*template.Template, error) {
|
||||
var err error
|
||||
mainTemplate = template.New("main")
|
||||
mainTemplate.Funcs(handlerFuncs(w, r))
|
||||
mainTemplate := template.New("main")
|
||||
mainTemplate, err = mainTemplate.Parse(mainTmpl)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
mainTemplate.Funcs(handlerFuncs(w, r))
|
||||
// render all templates
|
||||
for _, temp := range templates {
|
||||
tmp, _ := source.TmplBox.String(temp)
|
||||
mainTemplate, err = mainTemplate.Parse(tmp)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// render all javascript files
|
||||
|
@ -208,22 +211,25 @@ func loadTemplate(w http.ResponseWriter, r *http.Request) error {
|
|||
mainTemplate, err = mainTemplate.Parse(tmp)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return err
|
||||
return mainTemplate, err
|
||||
}
|
||||
|
||||
// ExecuteResponse will render a HTTP response for the front end user
|
||||
func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}, redirect interface{}) {
|
||||
if url, ok := redirect.(string); ok {
|
||||
http.Redirect(w, r, url, http.StatusSeeOther)
|
||||
http.Redirect(w, r, basePath+url, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
if usingSSL {
|
||||
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
||||
}
|
||||
loadTemplate(w, r)
|
||||
mainTemplate, err := loadTemplate(w, r)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
render, err := source.TmplBox.String(file)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
|
|
|
@ -54,7 +54,7 @@ func authenticated(handler func(w http.ResponseWriter, r *http.Request), redirec
|
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsFullAuthenticated(r) {
|
||||
if redirect {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
||||
} else {
|
||||
sendUnauthorizedJson(w, r)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func readOnly(handler func(w http.ResponseWriter, r *http.Request), redirect boo
|
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsReadAuthenticated(r) {
|
||||
if redirect {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
||||
} else {
|
||||
sendUnauthorizedJson(w, r)
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ func testNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
|||
fakeNotifer, notif, err := notifier.SelectNotifier(method)
|
||||
if err != nil {
|
||||
log.Errorln(fmt.Sprintf("issue saving notifier %v: %v", method, err))
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "settings")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -39,25 +39,30 @@ func Router() *mux.Router {
|
|||
dir := utils.Directory
|
||||
CacheStorage = NewStorage()
|
||||
r := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
if os.Getenv("AUTH_USERNAME") != "" && os.Getenv("AUTH_PASSWORD") != "" {
|
||||
authUser = os.Getenv("AUTH_USERNAME")
|
||||
authPass = os.Getenv("AUTH_PASSWORD")
|
||||
r.Use(basicAuthHandler)
|
||||
}
|
||||
if basePath != "/" {
|
||||
r = r.PathPrefix(basePath).Subrouter()
|
||||
}
|
||||
|
||||
r.Use(sendLog)
|
||||
r.Handle("/", http.HandlerFunc(indexHandler))
|
||||
if source.UsingAssets(dir) {
|
||||
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
|
||||
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir(dir+"/assets/css"))))
|
||||
r.PathPrefix("/font/").Handler(http.StripPrefix("/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
||||
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(http.Dir(dir+"/assets/js"))))
|
||||
r.PathPrefix("/css/").Handler(http.StripPrefix(basePath+"/css/", http.FileServer(http.Dir(dir+"/assets/css"))))
|
||||
r.PathPrefix("/font/").Handler(http.StripPrefix(basePath+"/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
||||
r.PathPrefix("/js/").Handler(http.StripPrefix(basePath+"/js/", http.FileServer(http.Dir(dir+"/assets/js"))))
|
||||
r.PathPrefix("/robots.txt").Handler(indexHandler)
|
||||
r.PathPrefix("/favicon.ico").Handler(indexHandler)
|
||||
r.PathPrefix("/banner.png").Handler(indexHandler)
|
||||
} else {
|
||||
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(source.CssBox.HTTPBox())))
|
||||
r.PathPrefix("/font/").Handler(http.StripPrefix("/font/", http.FileServer(source.FontBox.HTTPBox())))
|
||||
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(source.JsBox.HTTPBox())))
|
||||
r.PathPrefix("/css/").Handler(http.StripPrefix(basePath+"/css/", http.FileServer(source.CssBox.HTTPBox())))
|
||||
r.PathPrefix("/font/").Handler(http.StripPrefix(basePath+"/font/", http.FileServer(source.FontBox.HTTPBox())))
|
||||
r.PathPrefix("/js/").Handler(http.StripPrefix(basePath+"/js/", http.FileServer(source.JsBox.HTTPBox())))
|
||||
r.PathPrefix("/robots.txt").Handler(http.FileServer(source.TmplBox.HTTPBox()))
|
||||
r.PathPrefix("/favicon.ico").Handler(http.FileServer(source.TmplBox.HTTPBox()))
|
||||
r.PathPrefix("/banner.png").Handler(http.FileServer(source.TmplBox.HTTPBox()))
|
||||
|
|
|
@ -73,7 +73,7 @@ func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
//notifiers.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "settings")
|
||||
}
|
||||
|
||||
func saveSASSHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -86,7 +86,7 @@ func saveSASSHandler(w http.ResponseWriter, r *http.Request) {
|
|||
source.SaveAsset([]byte(mobile), utils.Directory, "scss/mobile.scss")
|
||||
source.CompileSASS(utils.Directory)
|
||||
resetRouter()
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "settings")
|
||||
}
|
||||
|
||||
func saveAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -101,7 +101,7 @@ func saveAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
log.Errorln("Default 'base.css' was inserted because SASS did not work.")
|
||||
}
|
||||
resetRouter()
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "settings")
|
||||
}
|
||||
|
||||
func deleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -109,7 +109,7 @@ func deleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
log.Errorln(fmt.Errorf("error deleting all assets %v", err))
|
||||
}
|
||||
resetRouter()
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
|
||||
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "settings")
|
||||
}
|
||||
|
||||
func bulkImportHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{define "form_checkin"}}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form class="ajax_form" action="/api/checkin" data-redirect="/service/{{.Id}}" method="POST">
|
||||
<form class="ajax_form" action="api/checkin" data-redirect="/service/{{.Id}}" method="POST">
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<label for="checkin_interval" class="col-form-label">Checkin Name</label>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
{{$message := .}}
|
||||
<form class="ajax_form" action="/api/groups{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/services" method="POST">
|
||||
<form class="ajax_form" action="api/groups{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="services" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Group Name</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
{{$message := .}}
|
||||
<form class="ajax_form" action="/api/messages{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/messages" method="POST">
|
||||
<form class="ajax_form" action="api/messages{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/messages" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Title</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{define "form_integration"}}
|
||||
{{$i := .Get}}
|
||||
<form class="integration_{{underscore $i.ShortName }}" action="/settings/integrator/{{ $i.ShortName }}" method="POST">
|
||||
<form class="integration_{{underscore $i.ShortName }}" action="settings/integrator/{{ $i.ShortName }}" method="POST">
|
||||
<input type="hidden" name="integrator" class="form-control" value="{{ $i.ShortName }}">
|
||||
{{if $i.ShortName}}<h4 class="text-capitalize">{{$i.ShortName}}</h4>{{end}}
|
||||
{{if $i.Description}}<p class="small text-muted">{{safe $i.Description}}</p>{{end}}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
{{$message := .}}
|
||||
<form class="ajax_form" action="/api/messages{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/messages" method="POST">
|
||||
<form class="ajax_form" action="api/messages{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="messages" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Title</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{define "form_notifier"}}
|
||||
{{$n := .Select}}
|
||||
<form class="ajax_form {{underscore $n.Method }}" data-func="SaveNotifier" action="/api/notifier/{{ $n.Method }}" method="POST">
|
||||
<form class="ajax_form {{underscore $n.Method }}" data-func="SaveNotifier" action="api/notifier/{{ $n.Method }}" method="POST">
|
||||
{{if $n.Title}}<h4 class="text-capitalize">{{$n.Title}}</h4>{{end}}
|
||||
{{if $n.Description}}<p class="small text-muted">{{safe $n.Description}}</p>{{end}}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
{{$s := .}}
|
||||
<form class="ajax_form" action="/api/services{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/services" method="POST">
|
||||
<form class="ajax_form" action="api/services{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="services" method="POST">
|
||||
<h4 class="mb-5 text-muted">Basic Information</h4>
|
||||
<div class="form-group row">
|
||||
<label for="service_name" class="col-sm-4 col-form-label">Service Name</label>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{define "form_user"}}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form class="ajax_form" action="/api/users{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="/users" method="POST">
|
||||
<form class="ajax_form" action="api/users{{if ne .Id 0}}/{{.Id}}{{end}}" data-redirect="users" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-4 col-form-label">Username</label>
|
||||
<div class="col-6 col-md-4">
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
<title>{{block "title" .}} {{end}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
||||
<meta name="description" content="{{block "description" .}}{{end}}">
|
||||
<base href="{{BasePath}}/">
|
||||
{{if USE_CDN}}
|
||||
<link rel="shortcut icon" type="image/x-icon" href="https://assets.statping.com/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.statping.com/base.css">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
{{ 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">
|
||||
<link rel="stylesheet" href="/font/all.css">
|
||||
<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">
|
||||
<link rel="stylesheet" href="font/all.css">
|
||||
{{end}}
|
||||
{{block "extra_css" .}} {{end}}
|
||||
</head>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
Incorrect login information submitted, try again.
|
||||
</div>
|
||||
{{ end }}
|
||||
<form action="/dashboard" class="spin_form" method="POST">
|
||||
<form action="dashboard" class="spin_form" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-2 col-form-label">Username</label>
|
||||
<div class="col-sm-10">
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
{{define "nav"}}
|
||||
{{$isAdmin := Auth}}
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="/">Statping</a>
|
||||
<a class="navbar-brand" href="#">Statping</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item{{ if eq URL "/dashboard" }} active{{ end }}">
|
||||
<a class="nav-link" href="/dashboard">Dashboard</a>
|
||||
<li class="nav-item{{ if eq URL "dashboard" }} active{{ end }}">
|
||||
<a class="nav-link" href="dashboard">Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item{{ if eq URL "/services" }} active{{ end }}">
|
||||
<a class="nav-link" href="/services">Services</a>
|
||||
<li class="nav-item{{ if eq URL "services" }} active{{ end }}">
|
||||
<a class="nav-link" href="services">Services</a>
|
||||
</li>
|
||||
<li class="nav-item{{ if eq URL "/users" }} active{{ end }}">
|
||||
<a class="nav-link" href="/users">Users</a>
|
||||
<li class="nav-item{{ if eq URL "users" }} active{{ end }}">
|
||||
<a class="nav-link" href="users">Users</a>
|
||||
</li>
|
||||
<li class="nav-item{{ if eq URL "/messages" }} active{{ end }}">
|
||||
<a class="nav-link" href="/messages">Messages</a>
|
||||
<li class="nav-item{{ if eq URL "messages" }} active{{ end }}">
|
||||
<a class="nav-link" href="messages">Messages</a>
|
||||
</li>
|
||||
{{ if $isAdmin }}
|
||||
<li class="nav-item{{ if eq URL "/settings" }} active{{ end }}">
|
||||
<a class="nav-link" href="/settings">Settings</a>
|
||||
<li class="nav-item{{ if eq URL "settings" }} active{{ end }}">
|
||||
<a class="nav-link" href="settings">Settings</a>
|
||||
</li>
|
||||
<li class="nav-item{{ if eq URL "/logs" }} active{{ end }}">
|
||||
<a class="nav-link" href="/logs">Logs</a>
|
||||
<li class="nav-item{{ if eq URL "logs" }} active{{ end }}">
|
||||
<a class="nav-link" href="logs">Logs</a>
|
||||
</li>
|
||||
{{end}}
|
||||
<li class="nav-item{{ if eq URL "/help" }} active{{ end }}">
|
||||
<a class="nav-link" href="/help">Help</a>
|
||||
<li class="nav-item{{ if eq URL "help" }} active{{ end }}">
|
||||
<a class="nav-link" href="help">Help</a>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<a class="nav-link" href="/logout">Logout</a>
|
||||
<a class="nav-link" href="logout">Logout</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
<script src="https://assets.statping.com/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/apexcharts.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
<script src="{{BasePath}}/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="{{BasePath}}/js/bootstrap.min.js"></script>
|
||||
<script src="{{BasePath}}/js/apexcharts.min.js"></script>
|
||||
<script src="{{BasePath}}/js/main.js"></script>
|
||||
{{end}}
|
||||
{{block "extra_scripts" .}} {{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
{{end}}
|
||||
<div class="tab-content" id="v-pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
|
||||
<form method="POST" action="/settings">
|
||||
<form method="POST" action="settings">
|
||||
<div class="form-group">
|
||||
<label for="project">Project Name</label>
|
||||
<input type="text" name="project" class="form-control" value="{{ .Name }}" id="project" placeholder="Great Uptime">
|
||||
|
@ -196,7 +196,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<form method="POST" action="/settings/css">
|
||||
<form method="POST" action="settings/css">
|
||||
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
|
||||
<li class="nav-item col text-center">
|
||||
<a class="nav-link active" id="pills-vars-tab" data-toggle="pill" href="#pills-vars" role="tab" aria-controls="pills-vars" aria-selected="true">Variables</a>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{{ .Error }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<form method="POST" id="setup_form" action="/setup">
|
||||
<form method="POST" id="setup_form" action="setup">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-group">
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package utils
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
func DirWritable(path string) (bool, error) {
|
||||
info, err := os.Stat(path)
|
||||
|
|
Loading…
Reference in New Issue