Add support for tabs
This commit is contained in:
parent
7b5f8a9882
commit
207e23778b
6 changed files with 50 additions and 12 deletions
|
|
@ -12,10 +12,12 @@ type Menuable interface {
|
||||||
|
|
||||||
Menu(r *http.Request) []MenuItem
|
Menu(r *http.Request) []MenuItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MenuItem represents an item inside the menu
|
||||||
type MenuItem struct {
|
type MenuItem struct {
|
||||||
Title string
|
Title string
|
||||||
Path template.URL
|
Path template.URL
|
||||||
Active bool
|
Active bool // Active, only used for tabs and crumbs
|
||||||
|
|
||||||
Priority MenuPriority
|
Priority MenuPriority
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,29 +13,29 @@ const Public = "/⛰/"
|
||||||
// AssetsDefault contains assets for the 'Default' entrypoint.
|
// AssetsDefault contains assets for the 'Default' entrypoint.
|
||||||
var AssetsDefault = Assets{
|
var AssetsDefault = Assets{
|
||||||
Scripts: `<script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script>`,
|
Scripts: `<script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script>`,
|
||||||
Styles: `<link rel="stylesheet" href="/⛰/Default.a1620182.css"><link rel="stylesheet" href="/⛰/Default.d8ae99b3.css">`,
|
Styles: `<link rel="stylesheet" href="/⛰/Default.7f0054bc.css"><link rel="stylesheet" href="/⛰/Default.d8ae99b3.css">`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetsUser contains assets for the 'User' entrypoint.
|
// AssetsUser contains assets for the 'User' entrypoint.
|
||||||
var AssetsUser = Assets{
|
var AssetsUser = Assets{
|
||||||
Scripts: `<script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/User.23a71b44.js"></script><script src="/⛰/User.869c9a74.js" nomodule defer></script>`,
|
Scripts: `<script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/User.23a71b44.js"></script><script src="/⛰/User.869c9a74.js" nomodule defer></script>`,
|
||||||
Styles: `<link rel="stylesheet" href="/⛰/Default.a1620182.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css">`,
|
Styles: `<link rel="stylesheet" href="/⛰/Default.7f0054bc.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css">`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetsAdmin contains assets for the 'Admin' entrypoint.
|
// AssetsAdmin contains assets for the 'Admin' entrypoint.
|
||||||
var AssetsAdmin = Assets{
|
var AssetsAdmin = Assets{
|
||||||
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script src="/⛰/Admin.b992cf94.js" nomodule defer></script>`,
|
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script src="/⛰/Admin.b992cf94.js" nomodule defer></script>`,
|
||||||
Styles: `<link rel="stylesheet" href="/⛰/Default.a1620182.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css">`,
|
Styles: `<link rel="stylesheet" href="/⛰/Default.7f0054bc.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css">`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetsAdminProvision contains assets for the 'AdminProvision' entrypoint.
|
// AssetsAdminProvision contains assets for the 'AdminProvision' entrypoint.
|
||||||
var AssetsAdminProvision = Assets{
|
var AssetsAdminProvision = Assets{
|
||||||
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script nomodule defer src="/⛰/Admin.b992cf94.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/AdminProvision.5bc6b324.js"></script><script src="/⛰/AdminProvision.53660f24.js" nomodule defer></script>`,
|
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script nomodule defer src="/⛰/Admin.b992cf94.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/AdminProvision.5bc6b324.js"></script><script src="/⛰/AdminProvision.53660f24.js" nomodule defer></script>`,
|
||||||
Styles: `<link rel="stylesheet" href="/⛰/Default.a1620182.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/AdminProvision.38d394c2.css">`,
|
Styles: `<link rel="stylesheet" href="/⛰/Default.7f0054bc.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/AdminProvision.38d394c2.css">`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetsAdminRebuild contains assets for the 'AdminRebuild' entrypoint.
|
// AssetsAdminRebuild contains assets for the 'AdminRebuild' entrypoint.
|
||||||
var AssetsAdminRebuild = Assets{
|
var AssetsAdminRebuild = Assets{
|
||||||
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script nomodule defer src="/⛰/Admin.b992cf94.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/AdminRebuild.ddc01020.js"></script><script src="/⛰/AdminRebuild.e4ce4c16.js" nomodule defer></script>`,
|
Scripts: `<script nomodule defer src="/⛰/User.869c9a74.js"></script><script nomodule defer src="/⛰/Admin.b992cf94.js"></script><script type="module" src="/⛰/User.23a71b44.js"></script><script type="module" src="/⛰/Admin.c0a122d2.js"></script><script type="module" src="/⛰/Default.38d394c2.js"></script><script src="/⛰/Default.38d394c2.js" nomodule defer></script><script type="module" src="/⛰/AdminRebuild.ddc01020.js"></script><script src="/⛰/AdminRebuild.e4ce4c16.js" nomodule defer></script>`,
|
||||||
Styles: `<link rel="stylesheet" href="/⛰/Default.a1620182.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/AdminRebuild.38d394c2.css">`,
|
Styles: `<link rel="stylesheet" href="/⛰/Default.7f0054bc.css"><link rel="stylesheet" href="/⛰/Admin.db3e959a.css"><link rel="stylesheet" href="/⛰/User.68febbf8.css"><link rel="stylesheet" href="/⛰/User.09b09c46.css"><link rel="stylesheet" href="/⛰/Admin.9d294a13.css"><link rel="stylesheet" href="/⛰/AdminRebuild.38d394c2.css">`,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -8,6 +8,11 @@ footer {
|
||||||
margin: 2em;
|
margin: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.tabs-menu {
|
||||||
|
float: left;
|
||||||
|
min-width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
nav.pure-menu, nav.breadcrumbs {
|
nav.pure-menu, nav.breadcrumbs {
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ type Flags struct {
|
||||||
assets.Assets // assets are the assets included in the template
|
assets.Assets // assets are the assets included in the template
|
||||||
|
|
||||||
Crumbs []component.MenuItem // crumbs are the breadcrumbs leading to a specific action
|
Crumbs []component.MenuItem // crumbs are the breadcrumbs leading to a specific action
|
||||||
|
Tabs []component.MenuItem // tabs are shown above actions, and act as a menu
|
||||||
Actions []component.MenuItem // actions are the actions available to a specific thingy
|
Actions []component.MenuItem // actions are the actions available to a specific thingy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,12 +78,10 @@ func Actions(actions ...component.MenuItem) FlagFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplaceAction replaces a specific action
|
// Tabs sets the tabs
|
||||||
func ReplaceAction(old component.MenuItem, action component.MenuItem) FlagFunc {
|
func Tabs(actions ...component.MenuItem) FlagFunc {
|
||||||
return func(flags Flags, r *http.Request) Flags {
|
return func(flags Flags, r *http.Request) Flags {
|
||||||
if !old.ReplaceWith(action, flags.Actions) {
|
flags.Tabs = slices.Clone(actions)
|
||||||
zerolog.Ctx(r.Context()).Warn().Str("action", fmt.Sprint(action)).Str("actions", fmt.Sprint(flags.Actions)).Msg("did not replace menu item")
|
|
||||||
}
|
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +96,26 @@ func ReplaceCrumb(old component.MenuItem, action component.MenuItem) FlagFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReplaceAction replaces a specific action
|
||||||
|
func ReplaceAction(old component.MenuItem, action component.MenuItem) FlagFunc {
|
||||||
|
return func(flags Flags, r *http.Request) Flags {
|
||||||
|
if !old.ReplaceWith(action, flags.Actions) {
|
||||||
|
zerolog.Ctx(r.Context()).Warn().Str("action", fmt.Sprint(action)).Str("actions", fmt.Sprint(flags.Actions)).Msg("did not replace menu item")
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceTab replaces a specific tab
|
||||||
|
func ReplaceTab(old component.MenuItem, tab component.MenuItem) FlagFunc {
|
||||||
|
return func(flags Flags, r *http.Request) Flags {
|
||||||
|
if !old.ReplaceWith(tab, flags.Tabs) {
|
||||||
|
zerolog.Ctx(r.Context()).Warn().Str("tab", fmt.Sprint(tab)).Str("tabs", fmt.Sprint(flags.Tabs)).Msg("did not replace menu item")
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Title sets the title of this template
|
// Title sets the title of this template
|
||||||
func Title(title string) FlagFunc {
|
func Title(title string) FlagFunc {
|
||||||
return func(flags Flags, r *http.Request) Flags {
|
return func(flags Flags, r *http.Request) Flags {
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,21 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
{{ if .Runtime.Flags.Tabs }}
|
||||||
|
<div class="pure-menu tabs-menu">
|
||||||
|
<ul class="pure-menu-list">
|
||||||
|
{{ range .Runtime.Flags.Tabs }}
|
||||||
|
<li class="pure-menu-item {{ if .Active }}pure-menu-selected{{ end }}">
|
||||||
|
<a href="{{ .Path }}" class="pure-menu-link">{{ .Title }}</a>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
<div class="pure-g" id="main">
|
<div class="pure-g" id="main">
|
||||||
{{ .Main }}
|
{{ .Main }}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue