added submit details page, started refractoring templates

main
Johannes Bülow 2024-02-23 18:39:05 +01:00
parent db0d541b74
commit 8dbc6d5129
Signed by untrusted user who does not match committer: jmb
GPG Key ID: B56971CF7B8F83A6
27 changed files with 839 additions and 79 deletions

View File

@ -50,8 +50,8 @@ func SubnetsList(filter *Subnet, limit int, offset int, order string) []Subnet {
return subnets return subnets
} }
func SubnetByID(id uint) Subnet { func SubnetByID(id uint) *Subnet {
var subnet Subnet var subnet Subnet
conn.First(&subnet, id) conn.First(&subnet, id)
return subnet return &subnet
} }

14
utils/stringMagic.go Normal file
View File

@ -0,0 +1,14 @@
package utils
import "fmt"
// SliceToLines() turns a slice of strings into a LF separated string)
func SliceToLines(slice []string) string {
var result string
for _, entry := range slice {
result += fmt.Sprint(entry, "\n")
}
return result
}

View File

@ -6,7 +6,6 @@ import (
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"git.jmbit.de/jmb/goipam/utils"
"git.jmbit.de/jmb/goipam/web/templates" "git.jmbit.de/jmb/goipam/web/templates"
) )
@ -24,10 +23,10 @@ func AuthMiddleware(requiredLevel int) gin.HandlerFunc {
} }
if accessLevelValue, ok := accessLevel.(int); ok { if accessLevelValue, ok := accessLevel.(int); ok {
if accessLevelValue < requiredLevel { if accessLevelValue < requiredLevel {
metaContent := utils.GenMetaContent(c) metaContent := templates.GenMetaContent(c)
metaContent.ErrorTitle = "Not Authorized" metaContent.ErrorTitle = "Not Authorized"
metaContent.ErrorText = "You are not authorized to do this Action" metaContent.ErrorText += "\nYou are not authorized to do this Action"
c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login", nil)) c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login"))
c.Abort() c.Abort()
return return
} }

View File

@ -0,0 +1,39 @@
package components
import "fmt"
//EditableFieldText() gives an Input field to write text into
templ EditableFieldText(target string, label string, content string) {
<form hx-post={ fmt.Sprint(templ.URL(target)) } hx-target="this" hx-swap="outerHTML">
<div class="field">
<label class="label">{ label }</label>
<div class="control">
<input class="input" type="text" name="value" value={ content }/>
</div>
</div>
</form>
}
//EditableFieldInt() gives an Input field to write text into
templ EditableFieldInt(target string, label string, content int) {
<form hx-post={ fmt.Sprint(templ.URL(target)) } hx-target="this" hx-swap="outerHTML">
<div class="field">
<label class="label">{ label }</label>
<div class="control">
<input class="input" type="number" name="value" value={ fmt.Sprint(content) }/>
</div>
<span class="material-icons icon is-small is-left">save</span>
</div>
</form>
}
//EditableField() is a generic component to make a single field editable
templ EditableField(target string, label string, content any) {
<div class="field" hx-target="this" hx-swap="outerHTML">
<label class="label">{ label }</label>
<div class="control">
<span class="input">{ fmt.Sprint(content) }</span>
<span class="material-icons icon is-small is-left">edit</span>
</div>
</div>
}

View File

@ -0,0 +1,116 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.543
package components
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import "context"
import "io"
import "bytes"
import "fmt"
func EditableText(target string, label string, content string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"field\" hx-target=\"this\" hx-swap=\"outerHTML\"><label class=\"label\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/components/editableTextField.templ`, Line: 6, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(content)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/components/editableTextField.templ`, Line: 7, Col: 11}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}
func EditableTextEdit(target string, label string, content string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprint(templ.URL(target))))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-target=\"this\" hx-swap=\"outerHTML\"><div class=\"field\"><label class=\"label\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/components/editableTextField.templ`, Line: 14, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> <input class=\"input\" type=\"text\" name=\"content\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(content))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div></form>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}

View File

@ -0,0 +1,6 @@
package components
templ LocationPicker() {
}

View File

@ -10,3 +10,16 @@ templ columns(columns ...templ.Component) {
} }
</div> </div>
} }
templ formField(label string, inputType string, name string, value string) {
<div class="field">
<label class="label">{ label }</label>
<input class="input" type={ inputType } name={ name } value={ value }/>
</div>
}
templ formFieldStatic(label string, inputType string, name string, value string) {
<div class="field">
<label class="label">{ label }</label> { value }
</div>
}

View File

@ -52,3 +52,114 @@ func columns(columns ...templ.Component) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
}) })
} }
func formField(label string, inputType string, name string, value string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"field\"><label class=\"label\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/formatting.templ`, Line: 15, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> <input class=\"input\" type=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(inputType))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(name))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(value))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}
func formFieldStatic(label string, inputType string, name string, value string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"field\"><label class=\"label\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/formatting.templ`, Line: 22, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/formatting.templ`, Line: 22, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}

View File

@ -2,8 +2,8 @@ package templates
import "fmt" import "fmt"
templ Index(metaContent MetaContent, counters IndexCounts, err error) { templ Index(metaContent MetaContent, counters IndexCounts) {
@wrapBase(metaContent, "GoIPAM", err) { @wrapBase(metaContent, "GoIPAM") {
<div class="section is-centered"> <div class="section is-centered">
<div class="container"> <div class="container">
@indexStats(counters) @indexStats(counters)

View File

@ -12,7 +12,7 @@ import "bytes"
import "fmt" import "fmt"
func Index(metaContent MetaContent, counters IndexCounts, err error) templ.Component { func Index(metaContent MetaContent, counters IndexCounts) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer { if !templ_7745c5c3_IsBuffer {
@ -48,7 +48,7 @@ func Index(metaContent MetaContent, counters IndexCounts, err error) templ.Compo
} }
return templ_7745c5c3_Err return templ_7745c5c3_Err
}) })
templ_7745c5c3_Err = wrapBase(metaContent, "GoIPAM", err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) templ_7745c5c3_Err = wrapBase(metaContent, "GoIPAM").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -1,7 +1,7 @@
package templates package templates
templ Login(metaContent MetaContent, title string, err error) { templ Login(metaContent MetaContent, title string) {
@wrapBase(metaContent, title, err) { @wrapBase(metaContent, title) {
<div class="section is-medium"> <div class="section is-medium">
<div class="columns is-centered"> <div class="columns is-centered">
<div class="column"> <div class="column">

View File

@ -10,7 +10,7 @@ import "context"
import "io" import "io"
import "bytes" import "bytes"
func Login(metaContent MetaContent, title string, err error) templ.Component { func Login(metaContent MetaContent, title string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer { if !templ_7745c5c3_IsBuffer {
@ -46,7 +46,7 @@ func Login(metaContent MetaContent, title string, err error) templ.Component {
} }
return templ_7745c5c3_Err return templ_7745c5c3_Err
}) })
templ_7745c5c3_Err = wrapBase(metaContent, title, err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) templ_7745c5c3_Err = wrapBase(metaContent, title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -93,14 +93,14 @@ templ ErrorMessage(title string, content string) {
} }
// wrapBase handles the basics of HTML // wrapBase handles the basics of HTML
templ wrapBase(metaContent MetaContent, title string, err error) { templ wrapBase(metaContent MetaContent, title string) {
<!DOCTYPE HTML> <!DOCTYPE HTML>
<html> <html>
@head(title) @head(title)
<body class="has-navbar-fixed-top"> <body class="has-navbar-fixed-top">
@navbar(metaContent.IsLoggedIn) @navbar(metaContent.IsLoggedIn)
if err != nil { if metaContent.ErrorText != "" {
@ErrorMessage("Error", err.Error()) @ErrorMessage(metaContent.ErrorTitle, metaContent.ErrorText)
} }
{ children... } { children... }
@footer(metaContent.Timestamp) @footer(metaContent.Timestamp)

View File

@ -198,7 +198,7 @@ func ErrorMessage(title string, content string) templ.Component {
} }
// wrapBase handles the basics of HTML // wrapBase handles the basics of HTML
func wrapBase(metaContent MetaContent, title string, err error) templ.Component { func wrapBase(metaContent MetaContent, title string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer { if !templ_7745c5c3_IsBuffer {
@ -227,8 +227,8 @@ func wrapBase(metaContent MetaContent, title string, err error) templ.Component
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if err != nil { if metaContent.ErrorText != "" {
templ_7745c5c3_Err = ErrorMessage("Error", err.Error()).Render(ctx, templ_7745c5c3_Buffer) templ_7745c5c3_Err = ErrorMessage(metaContent.ErrorTitle, metaContent.ErrorText).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -3,8 +3,8 @@ package templates
import "git.jmbit.de/jmb/goipam/db" import "git.jmbit.de/jmb/goipam/db"
templ ProfilePage(metaContent MetaContent, title string, user *db.User, err error) { templ ProfilePage(metaContent MetaContent, title string, user *db.User) {
@wrapBase(metaContent, title, err) { @wrapBase(metaContent, title) {
@profileMain(user) @profileMain(user)
} }
} }

View File

@ -12,7 +12,7 @@ import "bytes"
import "git.jmbit.de/jmb/goipam/db" import "git.jmbit.de/jmb/goipam/db"
func ProfilePage(metaContent MetaContent, title string, user *db.User, err error) templ.Component { func ProfilePage(metaContent MetaContent, title string, user *db.User) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer { if !templ_7745c5c3_IsBuffer {
@ -40,7 +40,7 @@ func ProfilePage(metaContent MetaContent, title string, user *db.User, err error
} }
return templ_7745c5c3_Err return templ_7745c5c3_Err
}) })
templ_7745c5c3_Err = wrapBase(metaContent, title, err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) templ_7745c5c3_Err = wrapBase(metaContent, title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -6,6 +6,8 @@ import (
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"git.jmbit.de/jmb/goipam/utils"
) )
type IndexCounts struct { type IndexCounts struct {
@ -31,6 +33,7 @@ func GenMetaContent(c *gin.Context) MetaContent {
sessionUserName := session.Get("username") sessionUserName := session.Get("username")
sessionIsLoggedIn := session.Get("isLoggedIn") sessionIsLoggedIn := session.Get("isLoggedIn")
sessionIsAdmin := session.Get("isAdmin") sessionIsAdmin := session.Get("isAdmin")
errorText := utils.SliceToLines(c.Errors.Errors())
var username string var username string
var isLoggedIn bool var isLoggedIn bool
var isAdmin bool var isAdmin bool
@ -57,5 +60,7 @@ func GenMetaContent(c *gin.Context) MetaContent {
IsLoggedIn: isLoggedIn, IsLoggedIn: isLoggedIn,
IsAdmin: isAdmin, IsAdmin: isAdmin,
Timestamp: fmt.Sprintf("%d", time.Now().Year()), Timestamp: fmt.Sprintf("%d", time.Now().Year()),
ErrorText: errorText,
ErrorTitle: "Error",
} }
} }

View File

@ -0,0 +1,72 @@
package templates
import "git.jmbit.de/jmb/goipam/db"
import "fmt"
templ SubnetDetails(metaContent MetaContent, title string, subnet *db.Subnet) {
@wrapBase(metaContent, title) {
@subnetMain(subnet)
}
}
templ subnetMain(subnet *db.Subnet) {
<div class="section is-medium">
<div class="container">
@SubnetStatic(subnet)
</div>
</div>
}
templ SubnetStatic(subnet *db.Subnet) {
<div hx-target="this" hx-swap="outerHTML">
<div class="field">
<label class="label">Subnet Name</label> { subnet.Name }
</div>
<div class="field">
<label class="label">Display Name</label> { subnet.DisplayName }
</div>
<div class="field">
<label class="label">VLAN</label> { fmt.Sprint(subnet.VLAN) }
</div>
<div class="field">
<label class="label">IPv4 Network Address</label> { subnet.IPv4Net }
</div>
<div class="field">
<label class="label">IPv6 Network Address</label> { subnet.IPv6Net }
</div>
<div class="field">
<label class="label">Location</label>
<a href={ templ.URL(fmt.Sprint("/locations/details/", subnet.LocationID)) }>
{ subnet.Location().Name }
</a>
</div>
<div class="field">
<label class="label">Comment</label> { fmt.Sprint(subnet.VLAN) }
</div>
<button hx-get={ fmt.Sprintf("/subnets/details/%d/edit.html", subnet.ID) } class="button is-primary">
Click To Edit
</button>
</div>
}
templ SubnetForm(subnet *db.Subnet) {
<form hx-post="/subnet/edit" hx-swap="outerHTML">
@formField("Name", "text", "name", subnet.Name)
@formField("Display Name", "text", "display-name", subnet.DisplayName)
@formField("VLAN", "number", "vlan", fmt.Sprint(subnet.VLAN))
@formField("IPv4 Network Address", "text", "ipv4", subnet.IPv4Net)
@formField("IPv6 Network Address", "text", "ipv6", subnet.IPv6Net)
<div class="field">
<label class="label">Location</label>
<a href={ templ.URL(fmt.Sprint("/locations/details/", subnet.LocationID)) }>
{ subnet.Location().Name }
</a>
</div>
@formField("Comment", "text", "comment", subnet.Comment)
<button class="button is-primary">Submit</button>
<button class="button is-light" hx-get={ fmt.Sprintf("/subnets/details/%d/edit.html", subnet.ID) }>Cancel</button>
</form>
}

View File

@ -0,0 +1,303 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.543
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import "context"
import "io"
import "bytes"
import "git.jmbit.de/jmb/goipam/db"
import "fmt"
func SubnetDetails(metaContent MetaContent, title string, subnet *db.Subnet) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
templ_7745c5c3_Err = subnetMain(subnet).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = wrapBase(metaContent, title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}
func subnetMain(subnet *db.Subnet) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-medium\"><div class=\"container\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = SubnetStatic(subnet).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}
func SubnetStatic(subnet *db.Subnet) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div hx-target=\"this\" hx-swap=\"outerHTML\"><div class=\"field\"><label class=\"label\">Subnet Name</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 23, Col: 57}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label class=\"label\">Display Name</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.DisplayName)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 26, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label class=\"label\">VLAN</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(subnet.VLAN))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 29, Col: 62}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label class=\"label\">IPv4 Network Address</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv4Net)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 32, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label class=\"label\">IPv6 Network Address</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv6Net)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 35, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label class=\"label\">Location</label> <a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 templ.SafeURL = templ.URL(fmt.Sprint("/locations/details/", subnet.LocationID))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Location().Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 40, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div class=\"field\"><label class=\"label\">Comment</label> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(subnet.VLAN))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 44, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><button hx-get=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("/subnets/details/%d/edit.html", subnet.ID)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"button is-primary\">Click To Edit</button></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}
func SubnetForm(subnet *db.Subnet) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form hx-post=\"/subnet/edit\" hx-swap=\"outerHTML\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("Name", "text", "name", subnet.Name).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("Display Name", "text", "display-name", subnet.DisplayName).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("VLAN", "number", "vlan", fmt.Sprint(subnet.VLAN)).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("IPv4 Network Address", "text", "ipv4", subnet.IPv4Net).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("IPv6 Network Address", "text", "ipv6", subnet.IPv6Net).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"field\"><label class=\"label\">Location</label> <a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 templ.SafeURL = templ.URL(fmt.Sprint("/locations/details/", subnet.LocationID))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var14)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Location().Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnetDetails.templ`, Line: 62, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = formField("Comment", "text", "comment", subnet.Comment).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<button class=\"button is-primary\">Submit</button> <button class=\"button is-light\" hx-get=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("/subnets/details/%d/edit.html", subnet.ID)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">Cancel</button></form>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}

View File

@ -3,8 +3,8 @@ package templates
import "git.jmbit.de/jmb/goipam/db" import "git.jmbit.de/jmb/goipam/db"
import "fmt" import "fmt"
templ SubnetsPage(metaContent MetaContent, subnets []db.Subnet, err error) { templ SubnetsPage(metaContent MetaContent, subnets []db.Subnet) {
@wrapBase(metaContent, "Subnets", err) { @wrapBase(metaContent, "Subnets") {
<div class="section is-centered"> <div class="section is-centered">
<div class="container"> <div class="container">
@subnetsTable(subnets) @subnetsTable(subnets)
@ -20,7 +20,6 @@ templ subnetsTable(subnets []db.Subnet) {
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>ID</th>
<th>Name</th> <th>Name</th>
<th>Display Name</th> <th>Display Name</th>
<th><abbr title="Virtual LAN ID">VLAN</abbr></th> <th><abbr title="Virtual LAN ID">VLAN</abbr></th>
@ -39,7 +38,6 @@ templ subnetsTable(subnets []db.Subnet) {
templ subnetsTableRows(subnets []db.Subnet) { templ subnetsTableRows(subnets []db.Subnet) {
for _, subnet := range subnets { for _, subnet := range subnets {
<tr hx-get={ fmt.Sprintf("/subnets/details/%d", subnet.ID) }> <tr hx-get={ fmt.Sprintf("/subnets/details/%d", subnet.ID) }>
<td>{ fmt.Sprint(subnet.ID) }</td>
<td>{ subnet.Name }</td> <td>{ subnet.Name }</td>
<td>{ subnet.DisplayName }</td> <td>{ subnet.DisplayName }</td>
<td>{ fmt.Sprint(subnet.VLAN) }</td> <td>{ fmt.Sprint(subnet.VLAN) }</td>

View File

@ -13,7 +13,7 @@ import "bytes"
import "git.jmbit.de/jmb/goipam/db" import "git.jmbit.de/jmb/goipam/db"
import "fmt" import "fmt"
func SubnetsPage(metaContent MetaContent, subnets []db.Subnet, err error) templ.Component { func SubnetsPage(metaContent MetaContent, subnets []db.Subnet) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer { if !templ_7745c5c3_IsBuffer {
@ -49,7 +49,7 @@ func SubnetsPage(metaContent MetaContent, subnets []db.Subnet, err error) templ.
} }
return templ_7745c5c3_Err return templ_7745c5c3_Err
}) })
templ_7745c5c3_Err = wrapBase(metaContent, "Subnets", err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) templ_7745c5c3_Err = wrapBase(metaContent, "Subnets").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -73,7 +73,7 @@ func subnetsTable(subnets []db.Subnet) templ.Component {
templ_7745c5c3_Var3 = templ.NopComponent templ_7745c5c3_Var3 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-centered\"><h2 class=\"title\">Subnets</h2><div class=\"table-container\"><table class=\"table\"><thead><tr><th>ID</th><th>Name</th><th>Display Name</th><th><abbr title=\"Virtual LAN ID\">VLAN</abbr></th><th><abbr title=\"IPv4 Address\">IPv4</abbr></th><th><abbr title=\"IPv6 Address\">IPv6</abbr></th><th>Location</th><th>Comment</th></tr></thead> <tbody id=\"search-results\"></tbody></table></div></div>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-centered\"><h2 class=\"title\">Subnets</h2><div class=\"table-container\"><table class=\"table\"><thead><tr><th>Name</th><th>Display Name</th><th><abbr title=\"Virtual LAN ID\">VLAN</abbr></th><th><abbr title=\"IPv4 Address\">IPv4</abbr></th><th><abbr title=\"IPv6 Address\">IPv6</abbr></th><th>Location</th><th>Comment</th></tr></thead> <tbody id=\"search-results\"></tbody></table></div></div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -111,9 +111,9 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var5 string var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(subnet.ID)) templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Name)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 41, Col: 30} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 40, Col: 20}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -124,9 +124,9 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var6 string var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Name) templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.DisplayName)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 42, Col: 20} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 41, Col: 27}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -137,9 +137,9 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var7 string var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.DisplayName) templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(subnet.VLAN))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 43, Col: 27} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 42, Col: 32}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -150,9 +150,9 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var8 string var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(subnet.VLAN)) templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv4Net)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 44, Col: 32} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 43, Col: 23}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -163,27 +163,14 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var9 string var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv4Net) templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv6Net)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 45, Col: 23} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 44, Col: 23}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.IPv6Net)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 46, Col: 23}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td hx-get=\"") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td hx-get=\"")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
@ -196,12 +183,12 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var11 string var templ_7745c5c3_Var10 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Location().Name) templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Location().Name)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 47, Col: 98} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 45, Col: 98}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -209,12 +196,12 @@ func subnetsTableRows(subnets []db.Subnet) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var12 string var templ_7745c5c3_Var11 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Comment) templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(subnet.Comment)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 48, Col: 23} return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/subnets.templ`, Line: 46, Col: 23}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -17,7 +17,7 @@ func index(c *gin.Context) {
LocationCount: db.CountLocations(), LocationCount: db.CountLocations(),
} }
c.HTML(http.StatusOK, "", templates.Index(templates.GenMetaContent(c), counters, nil)) c.HTML(http.StatusOK, "", templates.Index(templates.GenMetaContent(c), counters))
} }
func getEmpty(c *gin.Context) { func getEmpty(c *gin.Context) {

View File

@ -12,7 +12,7 @@ import (
) )
func getLogin(c *gin.Context) { func getLogin(c *gin.Context) {
c.HTML(http.StatusOK, "", templates.Login(templates.GenMetaContent(c), "Login", nil)) c.HTML(http.StatusOK, "", templates.Login(templates.GenMetaContent(c), "Login"))
} }
func postLogin(c *gin.Context) { func postLogin(c *gin.Context) {
@ -21,10 +21,9 @@ func postLogin(c *gin.Context) {
password := c.PostForm("password") password := c.PostForm("password")
err := auth.CheckPassword(username, password, session) err := auth.CheckPassword(username, password, session)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
metaContent := templates.GenMetaContent(c) metaContent := templates.GenMetaContent(c)
metaContent.ErrorTitle = "Error" c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login"))
metaContent.ErrorText = err.Error()
c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login", err))
log.Println(err) log.Println(err)
return return
} else { } else {

View File

@ -19,20 +19,21 @@ func getProfile(c *gin.Context) {
user, err := db.GetUserByName(username) user, err := db.GetUserByName(username)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",
templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user, err, templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user),
) )
} }
c.HTML( c.HTML(
http.StatusOK, http.StatusOK,
"", "",
templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user, nil), templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user),
) )
} else { } else {
c.HTML(http.StatusNotFound, "", templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user, nil)) c.HTML(http.StatusNotFound, "", templates.ProfilePage(templates.GenMetaContent(c), "User Profile", &user))
} }
} }
@ -45,6 +46,8 @@ func getProfileEdit(c *gin.Context) {
user, err := db.GetUserByName(username) user, err := db.GetUserByName(username)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",
@ -71,6 +74,7 @@ func postProfileEdit(c *gin.Context) {
user, err := db.GetUserByName(username) user, err := db.GetUserByName(username)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",
@ -102,6 +106,7 @@ func postPassword(c *gin.Context) {
user, err := db.GetUserByName(username) user, err := db.GetUserByName(username)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",
@ -110,6 +115,7 @@ func postPassword(c *gin.Context) {
} }
passHash, err := utils.HashPassword(password) passHash, err := utils.HashPassword(password)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",
@ -118,6 +124,7 @@ func postPassword(c *gin.Context) {
} }
db.SetUserPassHash(user, passHash) db.SetUserPassHash(user, passHash)
if err != nil { if err != nil {
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
c.HTML( c.HTML(
http.StatusInternalServerError, http.StatusInternalServerError,
"", "",

View File

@ -13,6 +13,11 @@ func GroupWeb(router *gin.Engine) *gin.Engine {
router.POST("/login.html", postLogin) router.POST("/login.html", postLogin)
router.GET("/profile/", getProfile) router.GET("/profile/", getProfile)
router.GET("/empty.html", getEmpty) router.GET("/empty.html", getEmpty)
subnetGroup := router.Group("/subnets")
subnetGroup.GET("/", getSubnetsPage)
subnetGroup.GET("/subnets/details/:id", getSubnetDetails)
subnetGroup.GET("/subnets/details/:id/:field", getSubnetDetailsField)
subnetGroup.POST("/subnets/details/:id/:field", postSubnetDetailsField)
return router return router

94
web/ui/subnetDetails.go Normal file
View File

@ -0,0 +1,94 @@
package ui
import (
"fmt"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"git.jmbit.de/jmb/goipam/db"
"git.jmbit.de/jmb/goipam/web/templates"
"git.jmbit.de/jmb/goipam/web/templates/components"
)
func getSubnetDetails(c *gin.Context) {
subnetIDint, err := strconv.Atoi(c.Param("id"))
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
subnetID := uint(subnetIDint)
subnet := db.SubnetByID(subnetID)
c.HTML(
http.StatusOK,
"",
templates.SubnetDetails(
templates.GenMetaContent(c),
fmt.Sprint("Subnet ", subnet.Name),
subnet,
),
)
}
func getSubnetDetailsField(c *gin.Context) {
subnetIDint, err := strconv.Atoi(c.Param("id"))
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
subnetID := uint(subnetIDint)
targetBase := fmt.Sprint("/subnet/details/", subnetID)
subnet := db.SubnetByID(subnetID)
switch c.Param("field") {
case "name":
c.HTML(
200,
"",
components.EditableTextEdit(fmt.Sprint(targetBase, "/name"), "Name", subnet.Name),
)
case "displayname":
c.HTML(
200,
"",
components.EditableTextEdit(
fmt.Sprint(targetBase, "/displayname"),
"Display Name",
subnet.DisplayName,
),
)
case "vlan":
c.HTML(
200,
"",
components.EditableIntEdit(fmt.Sprint(targetBase, "/vlan"), "VLAN ID", subnet.Name),
)
case "ipv4":
c.HTML(
200,
"",
components.EditableTextEdit(
fmt.Sprint(targetBase, "/ipv4"),
"IPv4 Network Address (CIDR)",
subnet.IPv4Net,
),
)
case "ipv6":
c.HTML(
200,
"",
components.EditableTextEdit(
fmt.Sprint(targetBase, "/ipv6"),
"IPv6 Network Address (CIDR)",
subnet.IPv6Net,
),
)
case "comment":
c.HTML(
200,
"",
components.EditableTextEdit(fmt.Sprint(targetBase, "/name"), "Name", subnet.Name),
)
default:
c.Redirect(http.StatusTemporaryRedirect, targetBase)
}
}

View File

@ -2,7 +2,6 @@ package ui
import ( import (
"net/http" "net/http"
"strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -12,13 +11,6 @@ import (
func getSubnetsPage(c *gin.Context) { func getSubnetsPage(c *gin.Context) {
subnets := db.SubnetsList(&db.Subnet{}, -1, -1, "") subnets := db.SubnetsList(&db.Subnet{}, -1, -1, "")
c.HTML(http.StatusOK, "", templates.SubnetsPage(templates.GenMetaContent(c), subnets, nil)) c.HTML(http.StatusOK, "", templates.SubnetsPage(templates.GenMetaContent(c), subnets))
} }
func getSubnetDetails(c *gin.Context) {
subnetID, err := strconv.Atoi(c.Param("id"))
c.Errors = append(c.Errors, &gin.Error{Err: err, Type: gin.ErrorTypeAny})
subnet := db.SubnetByID(subnetID)
}