Add Show Widget for library actions with Overview charts from last run output.
This commit is contained in:
@@ -17,31 +17,38 @@ type actionsResponse struct {
|
||||
}
|
||||
|
||||
type createActionRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Kind settings.ActionKind `json:"kind"`
|
||||
Body string `json:"body"`
|
||||
Env []settings.ActionEnvVar `json:"env"`
|
||||
RequiresSudo bool `json:"requires_sudo"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Kind settings.ActionKind `json:"kind"`
|
||||
Body string `json:"body"`
|
||||
Env []settings.ActionEnvVar `json:"env"`
|
||||
RequiresSudo bool `json:"requires_sudo"`
|
||||
ShowWidget bool `json:"show_widget"`
|
||||
WidgetType settings.ActionWidgetType `json:"widget_type"`
|
||||
}
|
||||
|
||||
type patchActionRequest struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
Body *string `json:"body"`
|
||||
Env *[]settings.ActionEnvVar `json:"env"`
|
||||
RequiresSudo *bool `json:"requires_sudo"`
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
Body *string `json:"body"`
|
||||
Env *[]settings.ActionEnvVar `json:"env"`
|
||||
RequiresSudo *bool `json:"requires_sudo"`
|
||||
ShowWidget *bool `json:"show_widget"`
|
||||
WidgetType *settings.ActionWidgetType `json:"widget_type"`
|
||||
}
|
||||
|
||||
var envVarNamePattern = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
|
||||
|
||||
var (
|
||||
errActionNameRequired = errors.New("action name is required")
|
||||
errActionBodyRequired = errors.New("action body is required")
|
||||
errActionKindInvalid = errors.New("action kind must be shell or script")
|
||||
errActionNotFound = errors.New("action not found")
|
||||
errActionBuiltinRO = errors.New("built-in actions cannot be modified")
|
||||
errActionIDRequired = errors.New("action id is required")
|
||||
errActionNameRequired = errors.New("action name is required")
|
||||
errActionBodyRequired = errors.New("action body is required")
|
||||
errActionKindInvalid = errors.New("action kind must be shell or script")
|
||||
errActionNotFound = errors.New("action not found")
|
||||
errActionBuiltinRO = errors.New("built-in actions cannot be modified")
|
||||
errActionBuiltinBodyRO = errors.New("built-in action body and name cannot be modified")
|
||||
errActionIDRequired = errors.New("action id is required")
|
||||
errActionWidgetTypeNeeded = errors.New("widget_type is required when show_widget is true")
|
||||
errActionWidgetTypeBad = errors.New("widget_type must be memory, disk, or raw")
|
||||
)
|
||||
|
||||
func actionsGetHandler(configDir string) http.HandlerFunc {
|
||||
@@ -120,26 +127,46 @@ func actionsPatchHandler(configDir string) http.HandlerFunc {
|
||||
writeJSON(writer, http.StatusNotFound, apiErrorResponse{Error: errActionNotFound.Error()})
|
||||
return
|
||||
}
|
||||
if store.Actions[index].Builtin {
|
||||
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: errActionBuiltinRO.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
updated := store.Actions[index]
|
||||
if payload.Name != nil {
|
||||
updated.Name = strings.TrimSpace(*payload.Name)
|
||||
isBuiltin := updated.Builtin
|
||||
if isBuiltin {
|
||||
if payload.Name != nil || payload.Description != nil || payload.Body != nil ||
|
||||
payload.Env != nil || payload.RequiresSudo != nil {
|
||||
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: errActionBuiltinBodyRO.Error()})
|
||||
return
|
||||
}
|
||||
if payload.ShowWidget == nil && payload.WidgetType == nil {
|
||||
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: errActionBuiltinRO.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
if payload.Description != nil {
|
||||
updated.Description = strings.TrimSpace(*payload.Description)
|
||||
|
||||
if !isBuiltin {
|
||||
if payload.Name != nil {
|
||||
updated.Name = strings.TrimSpace(*payload.Name)
|
||||
}
|
||||
if payload.Description != nil {
|
||||
updated.Description = strings.TrimSpace(*payload.Description)
|
||||
}
|
||||
if payload.Body != nil {
|
||||
updated.Body = strings.TrimSpace(*payload.Body)
|
||||
}
|
||||
if payload.Env != nil {
|
||||
updated.Env = *payload.Env
|
||||
}
|
||||
if payload.RequiresSudo != nil {
|
||||
updated.RequiresSudo = *payload.RequiresSudo
|
||||
}
|
||||
}
|
||||
if payload.Body != nil {
|
||||
updated.Body = strings.TrimSpace(*payload.Body)
|
||||
if payload.ShowWidget != nil {
|
||||
updated.ShowWidget = *payload.ShowWidget
|
||||
}
|
||||
if payload.Env != nil {
|
||||
updated.Env = *payload.Env
|
||||
if payload.WidgetType != nil {
|
||||
updated.WidgetType = *payload.WidgetType
|
||||
}
|
||||
if payload.RequiresSudo != nil {
|
||||
updated.RequiresSudo = *payload.RequiresSudo
|
||||
if !updated.ShowWidget {
|
||||
updated.WidgetType = settings.ActionWidgetTypeNone
|
||||
}
|
||||
updated.UpdatedAt = time.Now().UTC()
|
||||
|
||||
@@ -147,6 +174,10 @@ func actionsPatchHandler(configDir string) http.HandlerFunc {
|
||||
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: err.Error()})
|
||||
return
|
||||
}
|
||||
if err := validateActionWidget(updated.ShowWidget, updated.WidgetType); err != nil {
|
||||
writeJSON(writer, http.StatusBadRequest, apiErrorResponse{Error: err.Error()})
|
||||
return
|
||||
}
|
||||
if updated.Env == nil {
|
||||
updated.Env = []settings.ActionEnvVar{}
|
||||
}
|
||||
@@ -212,6 +243,13 @@ func buildCustomAction(payload createActionRequest) (settings.Action, error) {
|
||||
if err := validateActionFields(name, payload.Kind, body, env); err != nil {
|
||||
return settings.Action{}, err
|
||||
}
|
||||
widgetType := payload.WidgetType
|
||||
if !payload.ShowWidget {
|
||||
widgetType = settings.ActionWidgetTypeNone
|
||||
}
|
||||
if err := validateActionWidget(payload.ShowWidget, widgetType); err != nil {
|
||||
return settings.Action{}, err
|
||||
}
|
||||
|
||||
actionID, err := auth.NewUUID()
|
||||
if err != nil {
|
||||
@@ -227,6 +265,8 @@ func buildCustomAction(payload createActionRequest) (settings.Action, error) {
|
||||
Body: body,
|
||||
Env: env,
|
||||
RequiresSudo: payload.RequiresSudo,
|
||||
ShowWidget: payload.ShowWidget,
|
||||
WidgetType: widgetType,
|
||||
Builtin: false,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
@@ -257,6 +297,20 @@ func validateActionFields(
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateActionWidget(showWidget bool, widgetType settings.ActionWidgetType) error {
|
||||
if !showWidget {
|
||||
return nil
|
||||
}
|
||||
switch widgetType {
|
||||
case settings.ActionWidgetTypeMemory, settings.ActionWidgetTypeDisk, settings.ActionWidgetTypeRaw:
|
||||
return nil
|
||||
case settings.ActionWidgetTypeNone:
|
||||
return errActionWidgetTypeNeeded
|
||||
default:
|
||||
return errActionWidgetTypeBad
|
||||
}
|
||||
}
|
||||
|
||||
func findActionIndex(actions []settings.Action, actionID string) int {
|
||||
for index := range actions {
|
||||
if actions[index].ID == actionID {
|
||||
|
||||
Reference in New Issue
Block a user