Skip to content

Commit

Permalink
Include template params in template (flow def expressions) inspection
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Jan 25, 2024
1 parent 9f700ac commit 83fbbd0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 35 deletions.
18 changes: 15 additions & 3 deletions flows/actions/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/nyaruka/goflow/assets"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/flows/events"
"github.com/nyaruka/goflow/utils"
)

func init() {
Expand Down Expand Up @@ -57,8 +58,19 @@ type TemplateParams struct {
Values map[string][]string
}

// LocalizationUUID gets the UUID which identifies this object for localization
func (p *TemplateParams) LocalizationUUID() uuids.UUID { return uuids.UUID(p.UUID) }
func (p *TemplateParams) EnumerateTemplates(localization flows.Localization, include func(i18n.Language, string)) {
for _, comp := range utils.SortedKeys(p.Values) {
for _, v := range p.Values[comp] {
include(i18n.NilLanguage, v)
}
for _, lang := range localization.Languages() {
lvals := localization.GetItemTranslation(lang, p.UUID, comp)
for _, v := range lvals {
include(lang, v)
}
}
}
}

func (p *TemplateParams) MarshalJSON() ([]byte, error) {
if p == nil {
Expand Down Expand Up @@ -100,7 +112,7 @@ func (p *TemplateParams) UnmarshalJSON(d []byte) error {
type Templating struct {
UUID uuids.UUID `json:"uuid" validate:"required,uuid4"`
Template *assets.TemplateReference `json:"template" validate:"required"`
Variables []string `json:"variables" engine:"localized,evaluated"`
Variables []string `json:"variables,omitempty" engine:"localized,evaluated"`
Params *TemplateParams `json:"params,omitempty"`
}

Expand Down
40 changes: 18 additions & 22 deletions flows/actions/testdata/send_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,6 @@
"uuid": "5722e1fd-fe32-4e74-ac78-3cf41a6adb7e",
"name": "affirmation"
},
"variables": [
"@contact.name",
"boy"
],
"params": {
"body": [
"@contact.name",
Expand Down Expand Up @@ -480,9 +476,7 @@
"boy"
],
"localizables": [
"Hi Ryan Lewis, who's a good boy?",
"@contact.name",
"boy"
"Hi Ryan Lewis, who's a good boy?"
],
"inspection": {
"dependencies": [
Expand Down Expand Up @@ -510,10 +504,6 @@
"uuid": "5722e1fd-fe32-4e74-ac78-3cf41a6adb7e",
"name": "affirmation"
},
"variables": [
"@contact.name",
"boy"
],
"params": {
"body": [
"@contact.name",
Expand Down Expand Up @@ -578,14 +568,14 @@
"templates": [
"Hi Ryan Lewis, who's a good boy?",
"@contact.name",
"niño",
"@contact.name",
"boy",
"@contact.name",
"niño"
],
"localizables": [
"Hi Ryan Lewis, who's a good boy?",
"@contact.name",
"boy"
"Hi Ryan Lewis, who's a good boy?"
],
"inspection": {
"dependencies": [
Expand All @@ -602,7 +592,7 @@
}
},
{
"description": "Msg with template but no variables",
"description": "Msg with template but no params or variables",
"action": {
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
Expand All @@ -612,8 +602,7 @@
"template": {
"uuid": "2edc8dfd-aef0-41cf-a900-8a71bdb00900",
"name": "wakeup"
},
"variables": []
}
}
},
"events": [
Expand Down Expand Up @@ -671,8 +660,7 @@
"template": {
"uuid": "2edc8dfd-aef0-41cf-a900-8a71bdb00900",
"name": "wakeup"
},
"variables": null
}
}
},
"localization": {
Expand Down Expand Up @@ -808,7 +796,7 @@
}
},
{
"description": "Use template translation with component params",
"description": "Use template translation with non body component params",
"action": {
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
Expand All @@ -826,7 +814,6 @@
"uuid": "ce00c80e-991a-4c03-b373-3273c23ee042",
"name": "gender_update"
},
"variables": null,
"params": {
"body": [
"@contact.name",
Expand Down Expand Up @@ -935,7 +922,16 @@
"Yes",
"No",
"Si",
"No"
"No",
"@contact.name",
"boy",
"@contact.name",
"niño",
"Yeah",
"Sip",
"Nope",
"http://templates.com/red.jpg",
"http://templates.com/rojo.jpg"
],
"localizables": [
"Hey Ryan Lewis, your gender is saved as boy.",
Expand Down
26 changes: 17 additions & 9 deletions flows/inspect/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,26 @@ func Templates(s any, localization flows.Localization, include func(i18n.Languag
}

func templateValues(v reflect.Value, localization flows.Localization, include func(i18n.Language, string)) {
walk(v, nil, func(sv reflect.Value, fv reflect.Value, ef *EngineField) {
if ef.Evaluated {
extractTemplates(fv, i18n.NilLanguage, include)
walk(v,
func(v reflect.Value) {
te, ok := v.Interface().(flows.TemplateEnumerator)
if ok {
te.EnumerateTemplates(localization, include)

Check warning on line 24 in flows/inspect/templates.go

View check run for this annotation

Codecov / codecov/patch

flows/inspect/templates.go#L24

Added line #L24 was not covered by tests
}
},
func(sv reflect.Value, fv reflect.Value, ef *EngineField) {
if ef.Evaluated {
extractTemplates(fv, i18n.NilLanguage, include)

// if this field is also localized, each translation is a template and needs to be included
if ef.Localized && localization != nil {
localizable := sv.Interface().(flows.Localizable)
// if this field is also localized, each translation is a template and needs to be included
if ef.Localized && localization != nil {
localizable := sv.Interface().(flows.Localizable)

Translations(localization, localizable.LocalizationUUID(), ef.JSONName, include)
Translations(localization, localizable.LocalizationUUID(), ef.JSONName, include)
}
}
}
})
},
)
}

func Translations(localization flows.Localization, itemUUID uuids.UUID, property string, include func(i18n.Language, string)) {
Expand Down
4 changes: 4 additions & 0 deletions flows/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ type Localizable interface {
LocalizationUUID() uuids.UUID
}

type TemplateEnumerator interface {
EnumerateTemplates(Localization, func(i18n.Language, string))
}

// Flow describes the ordered logic of actions and routers
type Flow interface {
Contextable
Expand Down
2 changes: 1 addition & 1 deletion utils/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Set[K constraints.Ordered](s []K) map[K]bool {
}

// SortedKeys returns the keys of a set in lexical order
func SortedKeys[K constraints.Ordered](m map[K]bool) []K {
func SortedKeys[K constraints.Ordered, V any](m map[K]V) []K {
keys := maps.Keys(m)
slices.Sort(keys)
return keys
Expand Down

0 comments on commit 83fbbd0

Please sign in to comment.