Add Show Widget for library actions with Overview charts from last run output.

This commit is contained in:
2026-07-20 20:48:06 +02:00
parent e047499fed
commit d188ca41b8
20 changed files with 1918 additions and 128 deletions
+33 -2
View File
@@ -54,6 +54,7 @@ type createActionGroupItemRequest struct {
RequiresSudo bool `json:"requires_sudo"`
SetVariable string `json:"set_variable"`
RunIf string `json:"run_if"`
WidgetLabel string `json:"widget_label"`
}
type patchActionGroupItemRequest struct {
@@ -65,6 +66,7 @@ type patchActionGroupItemRequest struct {
RequiresSudo *bool `json:"requires_sudo"`
SetVariable *string `json:"set_variable"`
RunIf *string `json:"run_if"`
WidgetLabel *string `json:"widget_label"`
}
type reorderActionGroupItemsRequest struct {
@@ -332,7 +334,7 @@ func (app *App) actionGroupItemsPatchHandler(writer http.ResponseWriter, request
return
}
item := store.Groups[groupIndex].Items[itemIndex]
editingBodyFields := payload.Name != nil || payload.Description != nil || payload.Kind != nil || payload.Body != nil || payload.Env != nil || payload.RequiresSudo != nil
editingBodyFields := payload.Name != nil || payload.Description != nil || payload.Kind != nil || payload.Body != nil || payload.RequiresSudo != nil
if item.Source != settings.ActionItemSourceLocal && editingBodyFields {
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: "library actions must be cloned before editing"})
return
@@ -364,6 +366,19 @@ func (app *App) actionGroupItemsPatchHandler(writer http.ResponseWriter, request
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: err.Error()})
return
}
} else if payload.Env != nil {
env := *payload.Env
if env == nil {
env = []settings.ActionEnvVar{}
}
for index := range env {
env[index].Name = strings.TrimSpace(env[index].Name)
if env[index].Name == "" || !envVarNamePattern.MatchString(env[index].Name) {
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: "environment variable name must match [A-Za-z_][A-Za-z0-9_]*"})
return
}
}
item.Env = env
}
if payload.SetVariable != nil {
@@ -382,6 +397,9 @@ func (app *App) actionGroupItemsPatchHandler(writer http.ResponseWriter, request
}
item.RunIf = runIf
}
if payload.WidgetLabel != nil {
item.WidgetLabel = strings.TrimSpace(*payload.WidgetLabel)
}
store.Groups[groupIndex].Items[itemIndex] = item
store.Groups[groupIndex].UpdatedAt = time.Now().UTC()
@@ -500,6 +518,7 @@ func (app *App) actionGroupItemsDeleteHandler(writer http.ResponseWriter, reques
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
return
}
_ = settings.DeleteActionWidgetsForItem(app.ConfigDir, node.ID, itemID)
writeJSON(writer, http.StatusOK, actionGroupResponse{Group: store.Groups[groupIndex]})
}
@@ -745,13 +764,24 @@ func buildNodeActionItem(payload createActionGroupItemRequest) (settings.NodeAct
if libraryID == "" {
return settings.NodeActionItem{}, errors.New("library_action_id is required")
}
env := payload.Env
if env == nil {
env = []settings.ActionEnvVar{}
}
for index := range env {
env[index].Name = strings.TrimSpace(env[index].Name)
if env[index].Name == "" || !envVarNamePattern.MatchString(env[index].Name) {
return settings.NodeActionItem{}, errors.New("environment variable name must match [A-Za-z_][A-Za-z0-9_]*")
}
}
return settings.NodeActionItem{
ID: itemID,
Source: settings.ActionItemSourceLibrary,
LibraryActionID: libraryID,
Env: []settings.ActionEnvVar{},
Env: env,
SetVariable: setVariable,
RunIf: runIf,
WidgetLabel: strings.TrimSpace(payload.WidgetLabel),
}, nil
case settings.ActionItemSourceLocal:
env := payload.Env
@@ -774,6 +804,7 @@ func buildNodeActionItem(payload createActionGroupItemRequest) (settings.NodeAct
RequiresSudo: payload.RequiresSudo,
SetVariable: setVariable,
RunIf: runIf,
WidgetLabel: strings.TrimSpace(payload.WidgetLabel),
}, nil
default:
return settings.NodeActionItem{}, errors.New("source must be library or local")