diff --git a/excellent/legacy.go b/excellent/legacy.go index 6130b1a06..6477be4fa 100644 --- a/excellent/legacy.go +++ b/excellent/legacy.go @@ -40,22 +40,33 @@ func (v vars) String() string { } type arbitraryVars struct { - vars vars - base string - nesting string + vars vars + base string + nesting string + nestedVars vars } func (v arbitraryVars) Resolve(key string) interface{} { + value, ok := v.vars[key] if ok { return fmt.Sprintf("%s.%s", v.base, value) } + prefix := v.base if v.nesting != "" { - return fmt.Sprintf("%s.%s.%s", v.base, v.nesting, key) + prefix = fmt.Sprintf("%s.%s", v.base, v.nesting) + } + + if v.nestedVars != nil { + return &arbitraryVars{ + base: fmt.Sprintf("%s.%s", prefix, key), + vars: v.nestedVars, + } } - return fmt.Sprintf("%s.%s", v.base, key) + return fmt.Sprintf("%s.%s", prefix, key) + } func (v arbitraryVars) Default() interface{} { @@ -140,6 +151,9 @@ func newVars() vars { }, "flow": arbitraryVars{ base: "run.results", + nestedVars: map[string]interface{}{ + "category": "category_localized", + }, }, "step": vars{ "value": "input.text", diff --git a/excellent/legacy_test.go b/excellent/legacy_test.go index 04b85f6e1..93d1aba1c 100644 --- a/excellent/legacy_test.go +++ b/excellent/legacy_test.go @@ -51,7 +51,7 @@ func TestTranslate(t *testing.T) { {old: "@contact.uuid", new: "@contact.uuid"}, {old: "@contact.blerg", new: "@contact.fields.blerg"}, {old: "@flow.blerg", new: "@run.results.blerg"}, - {old: "@flow.blerg.category", new: "@run.results.blerg.category"}, + {old: "@flow.blerg.category", new: "@run.results.blerg.category_localized"}, {old: "@step.value", new: "@input.text"}, {old: "@step.contact", new: "@step.contact"}, {old: "@date.now", new: "@(now())"}, diff --git a/flows/actions/save_flow_result.go b/flows/actions/save_flow_result.go index 217737e0d..04650ce8a 100644 --- a/flows/actions/save_flow_result.go +++ b/flows/actions/save_flow_result.go @@ -55,22 +55,20 @@ func (a *SaveFlowResultAction) Execute(run flows.FlowRun, step flows.Step) error } template = run.GetText(flows.UUID(a.UUID), "category", a.Category) - category, err := excellent.EvaluateTemplateAsString(run.Environment(), run.Context(), template) + categoryLocalized, err := excellent.EvaluateTemplateAsString(run.Environment(), run.Context(), template) if err != nil { run.AddError(step, err) } - // log our event - var categoryOriginal string - if template != a.Category { - categoryOriginal = a.Category + if a.Category == categoryLocalized { + categoryLocalized = "" } - event := events.NewSaveFlowResult(step.NodeUUID(), a.ResultName, value, category, categoryOriginal) + event := events.NewSaveFlowResult(step.NodeUUID(), a.ResultName, value, a.Category, categoryLocalized) run.AddEvent(step, event) // and save our result - run.Results().Save(step.NodeUUID(), a.ResultName, value, a.Category, categoryOriginal, *event.CreatedOn()) + run.Results().Save(step.NodeUUID(), a.ResultName, value, a.Category, categoryLocalized, *event.CreatedOn()) return nil } diff --git a/flows/engine/engine.go b/flows/engine/engine.go index 266ce6382..4456a228b 100644 --- a/flows/engine/engine.go +++ b/flows/engine/engine.go @@ -239,7 +239,6 @@ func pickNodeExit(run flows.FlowRun, node flows.Node, step flows.Step) (flows.No var exitUUID flows.ExitUUID var exit flows.Exit var exitName string - var exitOriginal string route := flows.NoRoute router := node.Router() @@ -266,7 +265,11 @@ func pickNodeExit(run flows.FlowRun, node flows.Node, step flows.Step) (flows.No // find our exit for _, e := range node.Exits() { if e.UUID() == exitUUID { - exitName = run.GetText(flows.UUID(exitUUID), "name", e.Name()) + + localizedName := run.GetText(flows.UUID(exitUUID), "name", e.Name()) + if localizedName != e.Name() { + exitName = localizedName + } exit = e break } @@ -278,13 +281,9 @@ func pickNodeExit(run flows.FlowRun, node flows.Node, step flows.Step) (flows.No // save our results if appropriate if router != nil && router.ResultName() != "" { - if exit != nil && exit.Name() != exitName { - exitOriginal = exit.Name() - } - - event := events.NewSaveFlowResult(node.UUID(), router.ResultName(), route.Match(), exitName, exitOriginal) + event := events.NewSaveFlowResult(node.UUID(), router.ResultName(), route.Match(), exit.Name(), exitName) run.AddEvent(step, event) - run.Results().Save(node.UUID(), router.ResultName(), route.Match(), exitName, exitOriginal, *event.CreatedOn()) + run.Results().Save(node.UUID(), router.ResultName(), route.Match(), exit.Name(), exitName, *event.CreatedOn()) } // log any error we received diff --git a/flows/events/save_flow_result.go b/flows/events/save_flow_result.go index da76e4e6a..fb94fa97f 100644 --- a/flows/events/save_flow_result.go +++ b/flows/events/save_flow_result.go @@ -24,16 +24,16 @@ const TypeSaveFlowResult string = "save_flow_result" // @event save_flow_result type SaveFlowResultEvent struct { BaseEvent - NodeUUID flows.NodeUUID `json:"node_uuid" validate:"required"` - ResultName string `json:"result_name" validate:"required"` - Value string `json:"value"` - Category string `json:"category"` - CategoryOriginal string `json:"category_original,omitempty"` + NodeUUID flows.NodeUUID `json:"node_uuid" validate:"required"` + ResultName string `json:"result_name" validate:"required"` + Value string `json:"value"` + Category string `json:"category"` + CategoryLocalized string `json:"category_localized,omitempty"` } // NewSaveFlowResult returns a new save result event for the passed in values -func NewSaveFlowResult(node flows.NodeUUID, name string, value string, exitName string, exitOriginal string) *SaveFlowResultEvent { - return &SaveFlowResultEvent{NodeUUID: node, ResultName: name, Value: value, Category: exitName, CategoryOriginal: exitOriginal} +func NewSaveFlowResult(node flows.NodeUUID, name string, value string, categoryName string, categoryLocalized string) *SaveFlowResultEvent { + return &SaveFlowResultEvent{NodeUUID: node, ResultName: name, Value: value, Category: categoryName, CategoryLocalized: categoryLocalized} } // Type returns the type of this event diff --git a/flows/results.go b/flows/results.go index dd3588761..1f0c6a713 100644 --- a/flows/results.go +++ b/flows/results.go @@ -20,8 +20,8 @@ type Results struct { } // Save saves a new result in our map. The key is saved in a snakified format -func (r *Results) Save(node NodeUUID, name string, value string, category string, categoryOriginal string, createdOn time.Time) { - result := Result{node, name, value, category, categoryOriginal, createdOn} +func (r *Results) Save(node NodeUUID, name string, value string, category string, categoryLocalized string, createdOn time.Time) { + result := Result{node, name, value, category, categoryLocalized, createdOn} r.results[utils.Snakify(name)] = &result } @@ -55,20 +55,28 @@ var _ utils.VariableResolver = (*Results)(nil) // Result represents a result value in our flow run. Results have a name for which they are the result for, // the value itself of the result, optional category and the date and node the result was collected on type Result struct { - node NodeUUID - name string - value string - category string - categoryOriginal string - createdOn time.Time + node NodeUUID + name string + value string + category string + categoryLocalized string + createdOn time.Time } // Resolve resolves the passed in key to a value. Result values have a name, value, category, node and created_on func (r *Result) Resolve(key string) interface{} { switch key { case "category": + if r.categoryLocalized != "" { + return r.categoryLocalized + } return r.category + case "category_localized": + if r.categoryLocalized == "" { + return r.category + } + return r.categoryLocalized case "created_on": return r.createdOn @@ -130,12 +138,12 @@ func (r *Results) MarshalJSON() ([]byte, error) { } type resultEnvelope struct { - Node NodeUUID `json:"node_uuid"` - Name string `json:"result_name"` - Value string `json:"value"` - Category string `json:"category,omitempty"` - CategoryOriginal string `json:"category_original,omitempty"` - CreatedOn time.Time `json:"created_on"` + Node NodeUUID `json:"node_uuid"` + Name string `json:"result_name"` + Value string `json:"value"` + Category string `json:"category,omitempty"` + CategoryLocalized string `json:"category_localized,omitempty"` + CreatedOn time.Time `json:"created_on"` } // UnmarshalJSON is our custom unmarshalling of a Result object @@ -148,7 +156,7 @@ func (r *Result) UnmarshalJSON(data []byte) error { r.name = re.Name r.value = re.Value r.category = re.Category - r.categoryOriginal = re.CategoryOriginal + r.categoryLocalized = re.CategoryLocalized r.createdOn = re.CreatedOn return err @@ -162,7 +170,7 @@ func (r *Result) MarshalJSON() ([]byte, error) { re.Name = r.name re.Value = r.value re.Category = r.category - re.CategoryOriginal = r.categoryOriginal + re.CategoryLocalized = r.categoryLocalized re.CreatedOn = r.createdOn return json.Marshal(re)