mirror of
https://github.com/OliveTin/OliveTin
synced 2025-12-13 09:35:37 +00:00
feature: Customizable default directory, back and action icons (#326)
This commit is contained in:
@@ -54,6 +54,7 @@ message DashboardComponent {
|
|||||||
string title = 1;
|
string title = 1;
|
||||||
string type = 2;
|
string type = 2;
|
||||||
repeated DashboardComponent contents = 3;
|
repeated DashboardComponent contents = 3;
|
||||||
|
string icon = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StartActionRequest {
|
message StartActionRequest {
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ type Config struct {
|
|||||||
InsecureAllowDumpJwtClaims bool
|
InsecureAllowDumpJwtClaims bool
|
||||||
Prometheus PrometheusConfig
|
Prometheus PrometheusConfig
|
||||||
SaveLogs SaveLogsConfig
|
SaveLogs SaveLogsConfig
|
||||||
|
DefaultIconForActions string
|
||||||
|
DefaultIconForDirectories string
|
||||||
|
DefaultIconForBack string
|
||||||
|
|
||||||
usedConfigDir string
|
usedConfigDir string
|
||||||
}
|
}
|
||||||
@@ -141,6 +144,7 @@ type DashboardComponent struct {
|
|||||||
Title string
|
Title string
|
||||||
Type string
|
Type string
|
||||||
Entity string
|
Entity string
|
||||||
|
Icon string
|
||||||
Contents []DashboardComponent
|
Contents []DashboardComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +179,9 @@ func DefaultConfig() *Config {
|
|||||||
config.InsecureAllowDumpJwtClaims = false
|
config.InsecureAllowDumpJwtClaims = false
|
||||||
config.Prometheus.Enabled = false
|
config.Prometheus.Enabled = false
|
||||||
config.Prometheus.DefaultGoMetrics = false
|
config.Prometheus.DefaultGoMetrics = false
|
||||||
|
config.DefaultIconForActions = "😀"
|
||||||
|
config.DefaultIconForDirectories = "📁"
|
||||||
|
config.DefaultIconForBack = "«"
|
||||||
|
|
||||||
return &config
|
return &config
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
var emojis = map[string]string{
|
var emojis = map[string]string{
|
||||||
"": "😀", // default icon
|
|
||||||
"poop": "💩",
|
"poop": "💩",
|
||||||
"smile": "😀",
|
"smile": "😀",
|
||||||
"ping": "📡",
|
"ping": "📡",
|
||||||
@@ -17,7 +16,11 @@ var emojis = map[string]string{
|
|||||||
"robot": "🤖",
|
"robot": "🤖",
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupHTMLIcon(keyToLookup string) string {
|
func lookupHTMLIcon(keyToLookup string, defaultIcon string) string {
|
||||||
|
if keyToLookup == "" {
|
||||||
|
return defaultIcon
|
||||||
|
}
|
||||||
|
|
||||||
if emoji, found := emojis[keyToLookup]; found {
|
if emoji, found := emojis[keyToLookup]; found {
|
||||||
return emoji
|
return emoji
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGetEmojiByShortName(t *testing.T) {
|
func TestGetEmojiByShortName(t *testing.T) {
|
||||||
assert.Equal(t, "😀", lookupHTMLIcon("smile"), "Find an eomji by short name")
|
assert.Equal(t, "😀", lookupHTMLIcon("smile", "empty"), "Find an eomji by short name")
|
||||||
|
|
||||||
assert.Equal(t, "notfound", lookupHTMLIcon("notfound"), "Find an eomji by undefined short name")
|
assert.Equal(t, "empty", lookupHTMLIcon("", "empty"), "Find an eomji when the value is empty")
|
||||||
|
|
||||||
|
assert.Equal(t, "notfound", lookupHTMLIcon("notfound", "empty"), "Find an eomji by undefined short name")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func (action *Action) sanitize(cfg *Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
action.ID = getActionID(action)
|
action.ID = getActionID(action)
|
||||||
action.Icon = lookupHTMLIcon(action.Icon)
|
action.Icon = lookupHTMLIcon(action.Icon, cfg.DefaultIconForActions)
|
||||||
action.PopupOnStart = sanitizePopupOnStart(action.PopupOnStart, cfg)
|
action.PopupOnStart = sanitizePopupOnStart(action.PopupOnStart, cfg)
|
||||||
|
|
||||||
if action.MaxConcurrent < 1 {
|
if action.MaxConcurrent < 1 {
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashb
|
|||||||
|
|
||||||
log.Tracef("GetDashboardComponents: %v", res)
|
log.Tracef("GetDashboardComponents: %v", res)
|
||||||
|
|
||||||
dashboardCfgToPb(res, cfg.Dashboards)
|
dashboardCfgToPb(res, cfg.Dashboards, cfg)
|
||||||
|
|
||||||
res.AuthenticatedUser = user.Username
|
res.AuthenticatedUser = user.Username
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import (
|
|||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dashboardCfgToPb(res *pb.GetDashboardComponentsResponse, dashboards []*config.DashboardComponent) {
|
func dashboardCfgToPb(res *pb.GetDashboardComponentsResponse, dashboards []*config.DashboardComponent, cfg *config.Config) {
|
||||||
for _, dashboard := range dashboards {
|
for _, dashboard := range dashboards {
|
||||||
res.Dashboards = append(res.Dashboards, &pb.DashboardComponent{
|
res.Dashboards = append(res.Dashboards, &pb.DashboardComponent{
|
||||||
Type: "dashboard",
|
Type: "dashboard",
|
||||||
Title: dashboard.Title,
|
Title: dashboard.Title,
|
||||||
Contents: getDashboardComponentContents(dashboard),
|
Contents: getDashboardComponentContents(dashboard, cfg),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDashboardComponentContents(dashboard *config.DashboardComponent) []*pb.DashboardComponent {
|
func getDashboardComponentContents(dashboard *config.DashboardComponent, cfg *config.Config) []*pb.DashboardComponent {
|
||||||
ret := make([]*pb.DashboardComponent, 0)
|
ret := make([]*pb.DashboardComponent, 0)
|
||||||
|
|
||||||
for _, subitem := range dashboard.Contents {
|
for _, subitem := range dashboard.Contents {
|
||||||
@@ -28,7 +28,8 @@ func getDashboardComponentContents(dashboard *config.DashboardComponent) []*pb.D
|
|||||||
newitem := &pb.DashboardComponent{
|
newitem := &pb.DashboardComponent{
|
||||||
Title: subitem.Title,
|
Title: subitem.Title,
|
||||||
Type: getDashboardComponentType(&subitem),
|
Type: getDashboardComponentType(&subitem),
|
||||||
Contents: getDashboardComponentContents(&subitem),
|
Contents: getDashboardComponentContents(&subitem, cfg),
|
||||||
|
Icon: getDashboardComponentIcon(&subitem, cfg),
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, newitem)
|
ret = append(ret, newitem)
|
||||||
@@ -37,6 +38,14 @@ func getDashboardComponentContents(dashboard *config.DashboardComponent) []*pb.D
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDashboardComponentIcon(item *config.DashboardComponent, cfg *config.Config) string {
|
||||||
|
if item.Icon == "" {
|
||||||
|
return cfg.DefaultIconForDirectories
|
||||||
|
}
|
||||||
|
|
||||||
|
return item.Icon
|
||||||
|
}
|
||||||
|
|
||||||
func getDashboardComponentType(item *config.DashboardComponent) string {
|
func getDashboardComponentType(item *config.DashboardComponent) string {
|
||||||
allowedTypes := []string{
|
allowedTypes := []string{
|
||||||
"stdout-most-recent-execution",
|
"stdout-most-recent-execution",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type webUISettings struct {
|
|||||||
CurrentVersion string
|
CurrentVersion string
|
||||||
PageTitle string
|
PageTitle string
|
||||||
SectionNavigationStyle string
|
SectionNavigationStyle string
|
||||||
|
DefaultIconForBack string
|
||||||
}
|
}
|
||||||
|
|
||||||
func findWebuiDir() string {
|
func findWebuiDir() string {
|
||||||
@@ -109,6 +110,7 @@ func generateWebUISettings(w http.ResponseWriter, r *http.Request) {
|
|||||||
CurrentVersion: updatecheck.CurrentVersion,
|
CurrentVersion: updatecheck.CurrentVersion,
|
||||||
PageTitle: cfg.PageTitle,
|
PageTitle: cfg.PageTitle,
|
||||||
SectionNavigationStyle: cfg.SectionNavigationStyle,
|
SectionNavigationStyle: cfg.SectionNavigationStyle,
|
||||||
|
DefaultIconForBack: cfg.DefaultIconForBack,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := w.Write([]byte(jsonRet))
|
_, err := w.Write([]byte(jsonRet))
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ function marshalDisplay (item, fieldset) {
|
|||||||
|
|
||||||
function marshalDirectoryButton (item, fieldset) {
|
function marshalDirectoryButton (item, fieldset) {
|
||||||
const directoryButton = document.createElement('button')
|
const directoryButton = document.createElement('button')
|
||||||
directoryButton.innerHTML = '<span class = "icon">📁</span> ' + item.title
|
directoryButton.innerHTML = '<span class = "icon">' + item.icon + '</span> ' + item.title
|
||||||
directoryButton.onclick = () => {
|
directoryButton.onclick = () => {
|
||||||
changeDirectory(item.title)
|
changeDirectory(item.title)
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ function marshalDirectory (item, section) {
|
|||||||
fs.style.display = 'none'
|
fs.style.display = 'none'
|
||||||
|
|
||||||
const directoryBackButton = document.createElement('button')
|
const directoryBackButton = document.createElement('button')
|
||||||
directoryBackButton.innerHTML = '«'
|
directoryBackButton.innerHTML = window.settings.DefaultIconForBack
|
||||||
directoryBackButton.title = 'Go back one directory'
|
directoryBackButton.title = 'Go back one directory'
|
||||||
directoryBackButton.onclick = () => {
|
directoryBackButton.onclick = () => {
|
||||||
changeDirectory('..')
|
changeDirectory('..')
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ function processWebuiSettingsJson (settings) {
|
|||||||
const titleElem = document.querySelector('#page-title')
|
const titleElem = document.querySelector('#page-title')
|
||||||
if (titleElem) titleElem.innerText = window.pageTitle
|
if (titleElem) titleElem.innerText = window.pageTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.settings = settings
|
||||||
}
|
}
|
||||||
|
|
||||||
function main () {
|
function main () {
|
||||||
|
|||||||
Reference in New Issue
Block a user