Adding even more components
- Starting on main manager page - Manager layout will be included in the manager page - Manager page will use htmx to load different components via api
This commit is contained in:
parent
5fd215d6dd
commit
223496075a
11
main.go
11
main.go
@ -4,10 +4,12 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
|
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
||||||
"git.staur.ca/stobbsm/clustvirt/view/static"
|
"git.staur.ca/stobbsm/clustvirt/view/static"
|
||||||
|
"github.com/a-h/templ"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/a-h/templ"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const DEBUG bool = true
|
const DEBUG bool = true
|
||||||
@ -28,6 +30,10 @@ func main() {
|
|||||||
|
|
||||||
// Start webserver and serve homepage
|
// Start webserver and serve homepage
|
||||||
|
|
||||||
|
defaultNavBar := []components.NavItem{
|
||||||
|
{Name: "Home", Href: "/"},
|
||||||
|
{Name: "About", Href: "/about"},
|
||||||
|
}
|
||||||
fs := http.StripPrefix("/static/", http.FileServer(http.Dir("public")))
|
fs := http.StripPrefix("/static/", http.FileServer(http.Dir("public")))
|
||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
@ -41,7 +47,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
fs.ServeHTTP(w, r)
|
fs.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
r.Get("/", templ.Handler(static.Home()).ServeHTTP)
|
r.Get("/", templ.Handler(layouts.Manager("Cluster Manager", "ClustVirt", defaultNavBar)).ServeHTTP)
|
||||||
|
r.Get("/about", templ.Handler(static.Home()).ServeHTTP)
|
||||||
|
|
||||||
log.Println(http.ListenAndServe(":3000", r))
|
log.Println(http.ListenAndServe(":3000", r))
|
||||||
}
|
}
|
||||||
|
@ -848,6 +848,26 @@ span>a:visited {
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.my-8 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-2 {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-4 {
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mr-auto {
|
.mr-auto {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
@ -856,10 +876,18 @@ span>a:visited {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-block {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-flex {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
.contents {
|
.contents {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
@ -868,6 +896,30 @@ span>a:visited {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.size-fit {
|
||||||
|
width: -moz-fit-content;
|
||||||
|
width: fit-content;
|
||||||
|
height: -moz-fit-content;
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-max {
|
||||||
|
width: -moz-max-content;
|
||||||
|
width: max-content;
|
||||||
|
height: -moz-max-content;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-72 {
|
||||||
|
width: 18rem;
|
||||||
|
height: 18rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-64 {
|
||||||
|
width: 16rem;
|
||||||
|
height: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
.h-4 {
|
.h-4 {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
}
|
}
|
||||||
@ -908,6 +960,52 @@ span>a:visited {
|
|||||||
height: 7rem;
|
height: 7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-44 {
|
||||||
|
height: 11rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-52 {
|
||||||
|
height: 13rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-36 {
|
||||||
|
height: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-40 {
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-max {
|
||||||
|
height: -moz-max-content;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-auto {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-48 {
|
||||||
|
height: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-56 {
|
||||||
|
height: 14rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-64 {
|
||||||
|
height: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-72 {
|
||||||
|
height: 18rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-fit {
|
||||||
|
height: -moz-fit-content;
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@ -933,10 +1031,55 @@ span>a:visited {
|
|||||||
width: 91.666667%;
|
width: 91.666667%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-6 {
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-40 {
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-44 {
|
||||||
|
width: 11rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-auto {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-48 {
|
||||||
|
width: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-52 {
|
||||||
|
width: 13rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-64 {
|
||||||
|
width: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-72 {
|
||||||
|
width: 18rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-max {
|
||||||
|
width: -moz-max-content;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-auto {
|
.flex-auto {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.basis-1\/2 {
|
.basis-1\/2 {
|
||||||
flex-basis: 50%;
|
flex-basis: 50%;
|
||||||
}
|
}
|
||||||
@ -969,6 +1112,14 @@ span>a:visited {
|
|||||||
flex-basis: 66.666667%;
|
flex-basis: 66.666667%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.basis-2\/4 {
|
||||||
|
flex-basis: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basis-2\/5 {
|
||||||
|
flex-basis: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
.list-inside {
|
.list-inside {
|
||||||
list-style-position: inside;
|
list-style-position: inside;
|
||||||
}
|
}
|
||||||
@ -1009,6 +1160,10 @@ span>a:visited {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.justify-between {
|
.justify-between {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
@ -9048,6 +9203,26 @@ span>a:visited {
|
|||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.self-center {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-self-end {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-self-center {
|
||||||
|
justify-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded-full {
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
|
|
||||||
.border-uiblue-100 {
|
.border-uiblue-100 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(221 231 248 / var(--tw-border-opacity));
|
border-color: rgb(221 231 248 / var(--tw-border-opacity));
|
||||||
@ -138667,6 +138842,11 @@ span>a:visited {
|
|||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.py-8 {
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.align-bottom {
|
.align-bottom {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
@ -220316,6 +220496,10 @@ span>a:visited {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md\:inline-flex {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
.md\:contents {
|
.md\:contents {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
BIN
public/images/home/logo-banner-dark-800.png
(Stored with Git LFS)
Normal file
BIN
public/images/home/logo-banner-dark-800.png
(Stored with Git LFS)
Normal file
Binary file not shown.
5
view/components/hero.templ
Normal file
5
view/components/hero.templ
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
templ Hero() {
|
||||||
|
{ children... }
|
||||||
|
}
|
35
view/components/hero_templ.go
Normal file
35
view/components/hero_templ.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.598
|
||||||
|
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"
|
||||||
|
|
||||||
|
func Hero() 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_Var1.Render(ctx, 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
|
||||||
|
})
|
||||||
|
}
|
40
view/components/navbar.templ
Normal file
40
view/components/navbar.templ
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
templ NavBar(hero templ.Component, navItems []NavItem) {
|
||||||
|
<nav
|
||||||
|
class={ "w-100",
|
||||||
|
"bg-uigrey-600",
|
||||||
|
"shadow",
|
||||||
|
"shadow-uigrey-700",
|
||||||
|
"rounded",
|
||||||
|
"rounded-full",
|
||||||
|
"md:px-auto" }
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class={ "md:h-16",
|
||||||
|
"h-28",
|
||||||
|
"mx-auto",
|
||||||
|
"md:px-4",
|
||||||
|
"container",
|
||||||
|
"flex",
|
||||||
|
"items-center",
|
||||||
|
"justify-between",
|
||||||
|
"flex-wrap",
|
||||||
|
"md:flex-nowrap" }
|
||||||
|
>
|
||||||
|
<a href="/">
|
||||||
|
@hero
|
||||||
|
</a>
|
||||||
|
<div class={ "text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3" }>
|
||||||
|
<ul class={ "flex", "justify-between", "sm:w-full", "md:w-auto" }>
|
||||||
|
for _, ni := range navItems {
|
||||||
|
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }>
|
||||||
|
<a href={ templ.URL(ni.Href) }>{ ni.Name }</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class={ "order-2", "md:order-3" }>Login</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
}
|
184
view/components/navbar_templ.go
Normal file
184
view/components/navbar_templ.go
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.598
|
||||||
|
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"
|
||||||
|
|
||||||
|
func NavBar(hero templ.Component, navItems []NavItem) 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)
|
||||||
|
var templ_7745c5c3_Var2 = []any{"w-100",
|
||||||
|
"bg-uigrey-600",
|
||||||
|
"shadow",
|
||||||
|
"shadow-uigrey-700",
|
||||||
|
"rounded",
|
||||||
|
"rounded-full",
|
||||||
|
"md:px-auto"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<nav class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var2).String()))
|
||||||
|
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_Var3 = []any{"md:h-16",
|
||||||
|
"h-28",
|
||||||
|
"mx-auto",
|
||||||
|
"md:px-4",
|
||||||
|
"container",
|
||||||
|
"flex",
|
||||||
|
"items-center",
|
||||||
|
"justify-between",
|
||||||
|
"flex-wrap",
|
||||||
|
"md:flex-nowrap"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var3).String()))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"/\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = hero.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 = []any{"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var4).String()))
|
||||||
|
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_Var5 = []any{"flex", "justify-between", "sm:w-full", "md:w-auto"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<ul class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var5).String()))
|
||||||
|
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
|
||||||
|
}
|
||||||
|
for _, ni := range navItems {
|
||||||
|
var templ_7745c5c3_Var6 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var6).String()))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var7 templ.SafeURL = templ.URL(ni.Href)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var7)))
|
||||||
|
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_Var8 string
|
||||||
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(ni.Name)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/navbar.templ`, Line: 31, Col: 47}
|
||||||
|
}
|
||||||
|
_, 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("</a></li>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</ul></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var9 = []any{"order-2", "md:order-3"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var9).String()))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">Login</div></div></nav>")
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
@ -4,6 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NavItem struct {
|
||||||
|
Name string
|
||||||
|
Href string
|
||||||
|
}
|
||||||
|
|
||||||
func NoWrapSize(size string) string {
|
func NoWrapSize(size string) string {
|
||||||
return fmt.Sprintf("%s:flex-nowrap", size)
|
return fmt.Sprintf("%s:flex-nowrap", size)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package layouts
|
package layouts
|
||||||
|
|
||||||
templ Manager(config LayoutConfig) {
|
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
|
|
||||||
|
templ Manager(title string, subtitle string, navBarItem []components.NavItem) {
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class={ "text-slate-50", "bg-slate-900" }>
|
<html class={ "text-slate-50", "bg-slate-900" }>
|
||||||
<head>
|
<head>
|
||||||
@ -9,11 +11,11 @@ templ Manager(config LayoutConfig) {
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header class={}>
|
<header class={"mx-4"}>
|
||||||
@header(config.MainTitle, config.SubTitle)
|
@header(title, subtitle, navBarItem)
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<footer>
|
<footer class={"mx-4"}>
|
||||||
@footer()
|
@footer()
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
@ -10,7 +10,9 @@ import "context"
|
|||||||
import "io"
|
import "io"
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
func Manager(config LayoutConfig) templ.Component {
|
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
|
|
||||||
|
func Manager(title string, subtitle string, navBarItem []components.NavItem) 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 {
|
||||||
@ -44,7 +46,7 @@ func Manager(config LayoutConfig) templ.Component {
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var3 = []any{}
|
var templ_7745c5c3_Var3 = []any{"mx-4"}
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
@ -61,11 +63,28 @@ func Manager(config LayoutConfig) templ.Component {
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = header(config.MainTitle, config.SubTitle).Render(ctx, templ_7745c5c3_Buffer)
|
templ_7745c5c3_Err = header(title, subtitle, navBarItem).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
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("</header><footer>")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</header>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 = []any{"mx-4"}
|
||||||
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<footer class=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var4).String()))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
@ -1,68 +1,41 @@
|
|||||||
package layouts
|
package layouts
|
||||||
|
|
||||||
templ StaticPage(title string, subtitle string) {
|
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class={ "text-uigrey-100" , "bg-uigrey-900" }>
|
|
||||||
|
|
||||||
<head>
|
templ StaticPage(title string, subtitle string, navBarItems []components.NavItem) {
|
||||||
<title>Clustvirt</title>
|
<!DOCTYPE html>
|
||||||
<link href="/static/css/style.css" type="text/css" rel="stylesheet" />
|
<html class={ "text-uigrey-100" , "bg-uigrey-900" }>
|
||||||
</head>
|
<head>
|
||||||
|
<title>Clustvirt</title>
|
||||||
<body>
|
<link href="/static/css/style.css" type="text/css" rel="stylesheet"/>
|
||||||
<header>
|
</head>
|
||||||
@header(title, subtitle)
|
<body>
|
||||||
</header>
|
<header>
|
||||||
<div id="content" name="content" class={ "flex" , "flex-col" , "gap-2" }>
|
@header(title, subtitle, navBarItems)
|
||||||
{ children... }
|
</header>
|
||||||
</div>
|
<div id="content" name="content" class={ "flex" , "flex-col" , "gap-2" }>
|
||||||
<footer>
|
{ children... }
|
||||||
@footer()
|
</div>
|
||||||
</footer>
|
<footer>
|
||||||
</body>
|
@footer()
|
||||||
|
</footer>
|
||||||
</html>
|
</body>
|
||||||
|
</html>
|
||||||
}
|
}
|
||||||
|
|
||||||
templ header(title string, subtitle string) {
|
templ hero(title string) {
|
||||||
<h2 class={ "text-lg" , "font-semibold" , "italic" , "h-6" }>{ subtitle }</h2>
|
<h1 class={ "text-2xl", "font-bold", "text-uiblue-200", "md:order-1" }>{ title }</h1>
|
||||||
@nav(title)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ nav(title string) {
|
templ header(title string, subtitle string, navBarItems []components.NavItem) {
|
||||||
<nav class={ "w-100" , "bg-uigrey-600" , "shadow" , "shadow-uigrey-700" , "md:px-auto" }>
|
<h2 class={ "text-lg" , "font-semibold" , "italic" , "h-6" }>{ subtitle }</h2>
|
||||||
<div class={
|
@components.NavBar(hero(title), navBarItems)
|
||||||
"md:h-16",
|
|
||||||
"h-28",
|
|
||||||
"mx-auto",
|
|
||||||
"md:px-4",
|
|
||||||
"container",
|
|
||||||
"flex",
|
|
||||||
"items-center",
|
|
||||||
"justify-between",
|
|
||||||
"flex-wrap",
|
|
||||||
"md:flex-nowrap" }>
|
|
||||||
<h1 class={ "text-2xl", "font-bold", "text-uiblue-200", "md:order-1" }>{ title }</h1>
|
|
||||||
<div class={"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}>
|
|
||||||
<ul class={ "flex", "justify-between", "sm:w-full", "md:w-auto" }>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">What</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Why</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Goals</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Stretch</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Requests</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Never</a></li>
|
|
||||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Notes</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class={"order-2", "md:order-3"}>Login</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ footer() {
|
templ footer() {
|
||||||
<div class="flex gap-4 md:gap-6 sm:gap-8 divide divide-solid">
|
<div class="flex gap-4 md:gap-6 sm:gap-8 divide divide-solid">
|
||||||
<div id="footer_left" class="flex-auto basis-1/4 md:basis-1/3 p-2">Left</div>
|
<div id="footer_left" class="flex-auto basis-1/4 md:basis-1/3 p-2">Left</div>
|
||||||
<div id="footer_middle" class="flex-auto basis-1/2 md:basis-1/3 p-2">Middle</div>
|
<div id="footer_middle" class="flex-auto basis-1/2 md:basis-1/3 p-2">Middle</div>
|
||||||
<div id="footer_right" class="flex-auto basis-1/4 md:basis-1/3 p-2">Right</div>
|
<div id="footer_right" class="flex-auto basis-1/4 md:basis-1/3 p-2">Right</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,9 @@ import "context"
|
|||||||
import "io"
|
import "io"
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
func StaticPage(title string, subtitle string) templ.Component {
|
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
|
|
||||||
|
func StaticPage(title string, subtitle string, navBarItems []components.NavItem) 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 {
|
||||||
@ -44,7 +46,7 @@ func StaticPage(title string, subtitle string) templ.Component {
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = header(title, subtitle).Render(ctx, templ_7745c5c3_Buffer)
|
templ_7745c5c3_Err = header(title, subtitle, navBarItems).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@ -92,7 +94,7 @@ func StaticPage(title string, subtitle string) templ.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func header(title string, subtitle string) templ.Component {
|
func hero(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 {
|
||||||
@ -105,12 +107,12 @@ func header(title string, subtitle string) templ.Component {
|
|||||||
templ_7745c5c3_Var4 = templ.NopComponent
|
templ_7745c5c3_Var4 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
var templ_7745c5c3_Var5 = []any{"text-lg", "font-semibold", "italic", "h-6"}
|
var templ_7745c5c3_Var5 = []any{"text-2xl", "font-bold", "text-uiblue-200", "md:order-1"}
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||||
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("<h2 class=\"")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h1 class=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@ -123,19 +125,15 @@ func header(title string, subtitle string) 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(subtitle)
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 27, Col: 71}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 26, Col: 80}
|
||||||
}
|
}
|
||||||
_, 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 {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2>")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1>")
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = nav(title).Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@ -146,7 +144,7 @@ func header(title string, subtitle string) templ.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func nav(title string) templ.Component {
|
func header(title string, subtitle string, navBarItems []components.NavItem) 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 {
|
||||||
@ -159,12 +157,12 @@ func nav(title string) templ.Component {
|
|||||||
templ_7745c5c3_Var7 = templ.NopComponent
|
templ_7745c5c3_Var7 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
var templ_7745c5c3_Var8 = []any{"w-100", "bg-uigrey-600", "shadow", "shadow-uigrey-700", "md:px-auto"}
|
var templ_7745c5c3_Var8 = []any{"text-lg", "font-semibold", "italic", "h-6"}
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
||||||
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("<nav class=\"")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h2 class=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@ -176,230 +174,20 @@ func nav(title string) templ.Component {
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var9 = []any{
|
var templ_7745c5c3_Var9 string
|
||||||
"md:h-16",
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
||||||
"h-28",
|
if templ_7745c5c3_Err != nil {
|
||||||
"mx-auto",
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 30, Col: 72}
|
||||||
"md:px-4",
|
}
|
||||||
"container",
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||||
"flex",
|
|
||||||
"items-center",
|
|
||||||
"justify-between",
|
|
||||||
"flex-wrap",
|
|
||||||
"md:flex-nowrap"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, 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("<div class=\"")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2>")
|
||||||
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(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var9).String()))
|
templ_7745c5c3_Err = components.NavBar(hero(title), navBarItems).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
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_Var10 = []any{"text-2xl", "font-bold", "text-uiblue-200", "md:order-1"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h1 class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var10).String()))
|
|
||||||
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(title)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 44, Col: 82}
|
|
||||||
}
|
|
||||||
_, 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("</h1>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var12 = []any{"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var12).String()))
|
|
||||||
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_Var13 = []any{"flex", "justify-between", "sm:w-full", "md:w-auto"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<ul class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var13).String()))
|
|
||||||
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_Var14 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var14).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">What</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var15 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var15).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Why</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var16 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var16).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Goals</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var17 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var17).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Stretch</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var18 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var18).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Requests</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var19 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var19).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Never</a></li>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var20 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var20).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Notes</a></li></ul></div>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var21 = []any{"order-2", "md:order-3"}
|
|
||||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var21).String()))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">Login</div></div></nav>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@ -418,9 +206,9 @@ func footer() templ.Component {
|
|||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
}
|
}
|
||||||
ctx = templ.InitializeContext(ctx)
|
ctx = templ.InitializeContext(ctx)
|
||||||
templ_7745c5c3_Var22 := templ.GetChildren(ctx)
|
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
|
||||||
if templ_7745c5c3_Var22 == nil {
|
if templ_7745c5c3_Var10 == nil {
|
||||||
templ_7745c5c3_Var22 = templ.NopComponent
|
templ_7745c5c3_Var10 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex gap-4 md:gap-6 sm:gap-8 divide divide-solid\"><div id=\"footer_left\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Left</div><div id=\"footer_middle\" class=\"flex-auto basis-1/2 md:basis-1/3 p-2\">Middle</div><div id=\"footer_right\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Right</div></div>")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex gap-4 md:gap-6 sm:gap-8 divide divide-solid\"><div id=\"footer_left\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Left</div><div id=\"footer_middle\" class=\"flex-auto basis-1/2 md:basis-1/3 p-2\">Middle</div><div id=\"footer_right\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Right</div></div>")
|
||||||
|
@ -1,249 +1,257 @@
|
|||||||
package static
|
package static
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
||||||
"git.staur.ca/stobbsm/clustvirt/view/components"
|
"git.staur.ca/stobbsm/clustvirt/view/components"
|
||||||
)
|
)
|
||||||
|
|
||||||
templ Home() {
|
templ Home() {
|
||||||
@layouts.StaticPage("ClustVirt", "Libvirt, clustered and managed") {
|
@layouts.StaticPage("ClustVirt", "Libvirt, clustered and managed", []components.NavItem{
|
||||||
@components.FlexRow(true) {
|
{Name: "What", Href: "#"},
|
||||||
<div class={ "basis-1/3" }>
|
{Name: "Why", Href: "#"},
|
||||||
@components.InfoBox("What is This?", "uiorange") {
|
{Name: "Goals", Href: "#"},
|
||||||
@components.ContentP() {
|
{Name: "Stretch", Href: "#"},
|
||||||
Clustvirt (work in progress name) aims to be the agnostic
|
{Name: "Requests", Href: "#"},
|
||||||
cluster controller for libvirtd. The server component is
|
{Name: "Never", Href: "#"},
|
||||||
used to display both the WebUI and run the REST API used to
|
{Name: "Notes", Href: "#"},
|
||||||
control one to many libvirtd hosts to manage virual machines,
|
}) {
|
||||||
LXC containers (through libvirtd), gather information about
|
<div>
|
||||||
each host, and monitor each host.
|
@components.InfoBox("What is This?", "uiorange") {
|
||||||
}
|
<div class={"mx-4"}>
|
||||||
}
|
@components.ContentP() {
|
||||||
</div>
|
Clustvirt (work in progress name) aims to be the agnostic
|
||||||
<div class={ "basis-2/3" }>
|
cluster controller for libvirtd. The server component is
|
||||||
@components.InfoBox("Why?", "uiblue") {
|
used to display both the WebUI and run the REST API used to
|
||||||
@components.List("informational") {
|
control one to many libvirtd hosts to manage virual machines,
|
||||||
@components.ListItem() {
|
LXC containers (through libvirtd), gather information about
|
||||||
Broadcom buying VMWare, and VMWare losing a free
|
each host, and monitor each host.
|
||||||
teir for homelabbers pissed me off
|
}
|
||||||
}
|
</div>
|
||||||
@components.ListItem() {
|
}
|
||||||
Vendor lock-in pisses me off
|
</div>
|
||||||
}
|
<div>
|
||||||
@components.ListItem() {
|
@components.InfoBox("Why?", "uiblue") {
|
||||||
Even good open source Hyperconverged systems
|
@components.List("informational") {
|
||||||
(Proxmox, as an example) exhibit a form of vendor lock-in
|
@components.ListItem() {
|
||||||
}
|
Broadcom buying VMWare, and VMWare losing a free
|
||||||
@components.ListItem() {
|
teir for homelabbers pissed me off
|
||||||
Libvirt is terrific, has the functionality for everything
|
}
|
||||||
those other providers do, but there really is not a great
|
@components.ListItem() {
|
||||||
option for those dipping their toes into Open Source
|
Vendor lock-in pisses me off
|
||||||
}
|
}
|
||||||
@components.ListItem() {
|
@components.ListItem() {
|
||||||
Its fun to build things that solve a need
|
Even good open source Hyperconverged systems
|
||||||
}
|
(Proxmox, as an example) exhibit a form of vendor lock-in
|
||||||
@components.ListItem() {
|
}
|
||||||
I really want to do it
|
@components.ListItem() {
|
||||||
}
|
Libvirt is terrific, has the functionality for everything
|
||||||
}
|
those other providers do, but there really is not a great
|
||||||
}
|
option for those dipping their toes into Open Source
|
||||||
</div>
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.FlexRow(true) {
|
Its fun to build things that solve a need
|
||||||
<div class={ "basis-7/12" }>
|
}
|
||||||
@components.InfoBox("Project Goals", "uigreen") {
|
@components.ListItem() {
|
||||||
@components.List("accepted") {
|
I really want to do it
|
||||||
@components.ListItem() {
|
}
|
||||||
Open source, currently on the MIT license
|
}
|
||||||
}
|
}
|
||||||
@components.ListItem() {
|
</div>
|
||||||
Base OS Agnostic. If it can run libvirtd, this should be able to control it on some level
|
<div>
|
||||||
}
|
@components.InfoBox("Project Goals", "uigreen") {
|
||||||
@components.ListItem() {
|
@components.List("accepted") {
|
||||||
Control the Virtual Machine life cycle on one or more libvirtd hosts
|
@components.ListItem() {
|
||||||
}
|
Open source, currently on the MIT license
|
||||||
@components.ListItem() {
|
}
|
||||||
Add clusting capabilities to libvirtd host, including;
|
@components.ListItem() {
|
||||||
}
|
Base OS Agnostic. If it can run libvirtd, this should be able to control it on some level
|
||||||
@components.ListItem() {
|
}
|
||||||
Migration of VMs
|
@components.ListItem() {
|
||||||
}
|
Control the Virtual Machine life cycle on one or more libvirtd hosts
|
||||||
@components.ListItem() {
|
}
|
||||||
Syncronizing secrets
|
@components.ListItem() {
|
||||||
}
|
Add clusting capabilities to libvirtd host, including;
|
||||||
@components.ListItem() {
|
}
|
||||||
Syncronizing VLANs, bridges, host only networking
|
@components.ListItem() {
|
||||||
}
|
Migration of VMs
|
||||||
@components.ListItem() {
|
}
|
||||||
Sharing HA storage availability
|
@components.ListItem() {
|
||||||
}
|
Syncronizing secrets
|
||||||
@components.ListItem() {
|
}
|
||||||
Locking shared resources like disks
|
@components.ListItem() {
|
||||||
}
|
Syncronizing VLANs, bridges, host only networking
|
||||||
@components.ListItem() {
|
}
|
||||||
Starting VMs marked for HA on another host when one goes down
|
@components.ListItem() {
|
||||||
}
|
Sharing HA storage availability
|
||||||
@components.ListItem() {
|
}
|
||||||
Manage a library of Cloud-init resources and templates to build new VMs quickly
|
@components.ListItem() {
|
||||||
}
|
Locking shared resources like disks
|
||||||
@components.ListItem() {
|
}
|
||||||
Local Storage management, including local directory, lvm, zfs (if installed)
|
@components.ListItem() {
|
||||||
}
|
Starting VMs marked for HA on another host when one goes down
|
||||||
@components.ListItem() {
|
}
|
||||||
Advanced Storage management, such as Ceph, glusterfs, drbd, iscsi, nfs
|
@components.ListItem() {
|
||||||
}
|
Manage a library of Cloud-init resources and templates to build new VMs quickly
|
||||||
@components.ListItem() {
|
}
|
||||||
Storage syncronization of local disks between hosts (zfs snapshots, lvm snapshots, rsync)
|
@components.ListItem() {
|
||||||
}
|
Local Storage management, including local directory, lvm, zfs (if installed)
|
||||||
@components.ListItem() {
|
}
|
||||||
Backup scheduling, creation, restoration
|
@components.ListItem() {
|
||||||
}
|
Advanced Storage management, such as Ceph, glusterfs, drbd, iscsi, nfs
|
||||||
}
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
</div>
|
Storage syncronization of local disks between hosts (zfs snapshots, lvm snapshots, rsync)
|
||||||
<div class={ "basis-5/12" }>
|
}
|
||||||
@components.InfoBox("Stretch Goals", "uipurple") {
|
@components.ListItem() {
|
||||||
@components.List("possible") {
|
Backup scheduling, creation, restoration
|
||||||
@components.ListItem() {
|
}
|
||||||
Install the OS which libvirtd is running on
|
}
|
||||||
}
|
}
|
||||||
@components.ListItem() {
|
</div>
|
||||||
Install/provision libvirtd on a host that does not have it installed
|
<div>
|
||||||
}
|
@components.InfoBox("Stretch Goals", "uipurple") {
|
||||||
@components.ListItem() {
|
@components.List("possible") {
|
||||||
Tools to move from one vendor to clustvirt/libvirtd
|
@components.ListItem() {
|
||||||
}
|
Install the OS which libvirtd is running on
|
||||||
@components.ListItem() {
|
}
|
||||||
VM templates for common aspects of VM creation and management,
|
@components.ListItem() {
|
||||||
like appliances
|
Install/provision libvirtd on a host that does not have it installed
|
||||||
}
|
}
|
||||||
@components.ListItem() {
|
@components.ListItem() {
|
||||||
External tool access that can be used to manage things that are not
|
Tools to move from one vendor to clustvirt/libvirtd
|
||||||
managed here (cephadm dashboard, for instance)
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
}
|
VM templates for common aspects of VM creation and management,
|
||||||
}
|
like appliances
|
||||||
</div>
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.FlexRow(true) {
|
External tool access that can be used to manage things that are not
|
||||||
<div class={ "basis-8/12" }>
|
managed here (cephadm dashboard, for instance)
|
||||||
@components.InfoBox("Reddit Requested Feature", "uiyellow") {
|
}
|
||||||
@components.List("possible") {
|
}
|
||||||
@components.ListItem() {
|
}
|
||||||
Search/Filter on hosts/vms - @Lopsided_Speaker_553
|
</div>
|
||||||
}
|
<div>
|
||||||
@components.ListItem() {
|
@components.InfoBox("Reddit Requested Feature", "uiyellow") {
|
||||||
Balance on resource usage per host/Automattically migrate to least
|
@components.List("possible") {
|
||||||
used host - @Lopsided_Speaker_553
|
@components.ListItem() {
|
||||||
}
|
Search/Filter on hosts/vms - @Lopsided_Speaker_553
|
||||||
@components.ListItem() {
|
}
|
||||||
Support inter-vm only commmunication (VxLAN style) - @Lopsided_Speaker_553
|
@components.ListItem() {
|
||||||
}
|
Balance on resource usage per host/Automattically migrate to least
|
||||||
@components.ListItem() {
|
used host - @Lopsided_Speaker_553
|
||||||
Deploy VMs using only API - @Lopsided_Speaker_553
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Support inter-vm only commmunication (VxLAN style) - @Lopsided_Speaker_553
|
||||||
Well documented, first class API - @kasperlitheater
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Deploy VMs using only API - @Lopsided_Speaker_553
|
||||||
Bootstrap service to configure a new server - @phatpappa_
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Well documented, first class API - @kasperlitheater
|
||||||
For the love of kitten, don't use XML as configuration files - @pascalbrax
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Bootstrap service to configure a new server - @phatpappa_
|
||||||
Expose the Cluster Manager functionalities as API - @raven2611
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
For the love of kitten, don't use XML as configuration files - @pascalbrax
|
||||||
CPU architecture awareness for migrations - @raven2611
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Expose the Cluster Manager functionalities as API - @raven2611
|
||||||
Inter VM Communications via VXLAN/EVPN - @raven2611
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
}
|
CPU architecture awareness for migrations - @raven2611
|
||||||
}
|
}
|
||||||
</div>
|
@components.ListItem() {
|
||||||
<div class={ "basis-4/12" }>
|
Inter VM Communications via VXLAN/EVPN - @raven2611
|
||||||
@components.InfoBox("Never Going to Happen", "uired") {
|
}
|
||||||
@components.List("never") {
|
}
|
||||||
@components.ListItem() {
|
}
|
||||||
Kubernetes
|
</div>
|
||||||
}
|
<div class={ }>
|
||||||
@components.ListItem() {
|
@components.InfoBox("Never Going to Happen", "uired") {
|
||||||
Application container management (docker, podman, etc)
|
@components.List("never") {
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Kubernetes
|
||||||
Become an OS
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Application container management (docker, podman, etc)
|
||||||
Have a paywall
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Become an OS
|
||||||
Vendor lock-in
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Have a paywall
|
||||||
Become a commercial entity (even indirectly)
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Vendor lock-in
|
||||||
Anything that does not have an Open Source standard behind it
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
@components.ListItem() {
|
Become a commercial entity (even indirectly)
|
||||||
Directly control a guest Operating System
|
}
|
||||||
}
|
@components.ListItem() {
|
||||||
}
|
Anything that does not have an Open Source standard behind it
|
||||||
}
|
}
|
||||||
</div>
|
@components.ListItem() {
|
||||||
}
|
Directly control a guest Operating System
|
||||||
@components.InfoBox("Other things to note", "uipink") {
|
}
|
||||||
@components.ContentP() {
|
}
|
||||||
I recently created a <span>@components.ANewTab("http://redd.it/1bct15z", "post")
|
}
|
||||||
</span>
|
</div>
|
||||||
on reddit announcing that I was building this, and while the majority
|
@components.InfoBox("Other things to note", "uipink") {
|
||||||
of responses were supportive, even offering features that may enhance
|
<div class={"flex", "flex-col", "gap-4", "mx-4"}>
|
||||||
what I originally set out to do, many responded with
|
@components.ContentP() {
|
||||||
"Why do we need another one??"
|
I recently created a
|
||||||
}
|
<span>
|
||||||
@components.ContentP() {
|
@components.ANewTab("http://redd.it/1bct15z", "post")
|
||||||
Besides the list above about why this exists, I wanted to clarify
|
</span>
|
||||||
a few things those individuals did not seeem to get: This is not
|
on reddit announcing that I was building this, and while the majority
|
||||||
a rebuild of Proxmox, Cloudstack, VMWare, Harvester or any of
|
of responses were supportive, even offering features that may enhance
|
||||||
the other "Hyper-converged/Single-solution/turnkey/Operating System"
|
what I originally set out to do, many responded with
|
||||||
offerings out there. This will not take over your base operating system
|
"Why do we need another one??"
|
||||||
on your machine, just act as a cluster manager and interface to access
|
}
|
||||||
the existing libvirtd instances on those machines, nor will it prescribe
|
@components.ContentP() {
|
||||||
a set of requirements that make it hard to move your own infrastructure
|
Besides the list above about why this exists, I wanted to clarify
|
||||||
around.
|
a few things those individuals did not seeem to get: This is not
|
||||||
}
|
a rebuild of Proxmox, Cloudstack, VMWare, Harvester or any of
|
||||||
@components.ContentP() {
|
the other "Hyper-converged/Single-solution/turnkey/Operating System"
|
||||||
At the heart of this project is that I hate the enshitifiation of
|
offerings out there. This will not take over your base operating system
|
||||||
Open Source that has been going on, where its just another way to make
|
on your machine, just act as a cluster manager and interface to access
|
||||||
money and control the eco system. RedHat tried to do it by locking
|
the existing libvirtd instances on those machines, nor will it prescribe
|
||||||
down their source code, Proxmox does it by making sure anything you
|
a set of requirements that make it hard to move your own infrastructure
|
||||||
do on Proxmox is tied to Proxmox (no offense to Proxmox), and even
|
around.
|
||||||
Hashicorp, who I loved so dearly, changed from a pure Open Source
|
}
|
||||||
licensing model to one that protects the business over the community
|
@components.ContentP() {
|
||||||
}
|
At the heart of this project is that I hate the enshitifiation of
|
||||||
@components.ContentP() {
|
Open Source that has been going on, where its just another way to make
|
||||||
I will not let that happen here.
|
money and control the eco system. RedHat tried to do it by locking
|
||||||
}
|
down their source code, Proxmox does it by making sure anything you
|
||||||
@components.ContentP() {
|
do on Proxmox is tied to Proxmox (no offense to Proxmox), and even
|
||||||
This project will seek to use the Unix philosophy, of building off
|
Hashicorp, who I loved so dearly, changed from a pure Open Source
|
||||||
of existing standards, combining tools, and having one tool do one
|
licensing model to one that protects the business over the community
|
||||||
job well. This does not mean there will be one application for each
|
}
|
||||||
aspect of the job, but that this application stack will manage Libvirtd
|
@components.ContentP() {
|
||||||
well, and have individual and configurable paths to manage each sub-aspect
|
I will not let that happen here.
|
||||||
of the libvirt stack. This stack will not create a Ceph cluster for you,
|
}
|
||||||
it leaves you to do that. It will not even talk to a ceph cluster.
|
@components.ContentP() {
|
||||||
It will, however, let you add that cluster via configuration options to
|
This project will seek to use the Unix philosophy, of building off
|
||||||
define it as a storage pool that libvirt can use.
|
of existing standards, combining tools, and having one tool do one
|
||||||
}
|
job well. This does not mean there will be one application for each
|
||||||
@components.ContentP() {
|
aspect of the job, but that this application stack will manage Libvirtd
|
||||||
If you want something that will allow you to use a single interface
|
well, and have individual and configurable paths to manage each sub-aspect
|
||||||
to create all sub aspects that can be used by libvirt
|
of the libvirt stack. This stack will not create a Ceph cluster for you,
|
||||||
(managing all firewall rules, creating a ceph cluster, etc.),
|
it leaves you to do that. It will not even talk to a ceph cluster.
|
||||||
use something like Proxmox which includes that builtin
|
It will, however, let you add that cluster via configuration options to
|
||||||
functionality. This isn't the stack for you.
|
define it as a storage pool that libvirt can use.
|
||||||
}
|
}
|
||||||
}
|
@components.ContentP() {
|
||||||
}
|
If you want something that will allow you to use a single interface
|
||||||
|
to create all sub aspects that can be used by libvirt
|
||||||
|
(managing all firewall rules, creating a ceph cluster, etc.),
|
||||||
|
use something like Proxmox which includes that builtin
|
||||||
|
functionality. This isn't the stack for you.
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user