Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions clicky_lookup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package clicky

import "github.com/flanksource/clicky/api"

type entityLookupResponse struct {
Filters map[string]entityLookupFilter `json:"filters"`
}

type entityLookupFilter struct {
Label string `json:"label,omitempty"`
Options map[string]clickyNode `json:"options,omitempty"`
Selected map[string]clickyNode `json:"selected,omitempty"`
Multi bool `json:"multi,omitempty"`
Type string `json:"type,omitempty"`
}

type clickyNode struct {
Kind string `json:"kind"`
Plain string `json:"plain,omitempty"`
Text string `json:"text,omitempty"`
Style *clickyStyle `json:"style,omitempty"`
Children []clickyNode `json:"children,omitempty"`
Tooltip *clickyNode `json:"tooltip,omitempty"`
}

type clickyStyle struct {
ClassName string `json:"className,omitempty"`
}

func toClickyNodeMap(values map[string]api.Textable) map[string]clickyNode {
if len(values) == 0 {
return nil
}

nodes := make(map[string]clickyNode, len(values))
for key, value := range values {
nodes[key] = toClickyNode(value)
}
return nodes
}

func toClickyNode(value api.Textable) clickyNode {
switch typed := value.(type) {
case api.Text:
return textToClickyNode(typed)
case *api.Text:
if typed == nil {
return clickyNode{Kind: "text"}
}
return textToClickyNode(*typed)
default:
if value == nil {
return clickyNode{Kind: "text"}
}
plain := value.String()
return clickyNode{
Kind: "text",
Text: plain,
Plain: plain,
}
}
}

func textToClickyNode(text api.Text) clickyNode {
node := clickyNode{
Kind: "text",
Text: text.Content,
Plain: text.String(),
}

if text.Style != "" {
node.Style = &clickyStyle{ClassName: text.Style}
}

if len(text.Children) > 0 {
node.Children = make([]clickyNode, 0, len(text.Children))
for _, child := range text.Children {
node.Children = append(node.Children, toClickyNode(child))
}
}

if text.Tooltip != nil {
tooltip := toClickyNode(text.Tooltip)
node.Tooltip = &tooltip
}

if node.Text == "" && node.Plain != "" {
node.Text = node.Plain
}

return node
}
11 changes: 11 additions & 0 deletions cobra_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import (
// that can invoke the user function directly with flag values.
var dataFuncRegistry sync.Map // map[*cobra.Command]func(flags map[string]string, args []string) (any, error)

// lookupFuncRegistry maps cobra commands to filter metadata lookup closures.
var lookupFuncRegistry sync.Map // map[*cobra.Command]func(flags map[string]string, args []string) (any, error)

// GetDataFunc returns the direct data function registered for a command, if any.
// Used by the RPC converter to wire DataFunc on RPCOperation.
func GetDataFunc(cmd *cobra.Command) func(flags map[string]string, args []string) (any, error) {
Expand All @@ -26,6 +29,14 @@ func GetDataFunc(cmd *cobra.Command) func(flags map[string]string, args []string
return nil
}

// GetLookupFunc returns the direct lookup function registered for a command, if any.
func GetLookupFunc(cmd *cobra.Command) func(flags map[string]string, args []string) (any, error) {
if v, ok := lookupFuncRegistry.Load(cmd); ok {
return v.(func(flags map[string]string, args []string) (any, error))
}
return nil
}

// AddCommand creates a Cobra command with automatic flag parsing from struct tags,
// execution, and result formatting.
//
Expand Down
Loading
Loading