From 850e4dacc55c36f24843e5b132de524e3e9b06fc Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 20 Aug 2022 16:22:54 +0800 Subject: [PATCH] [add] language pack support for chart --- chart/chart.go | 7 ++ chart/chart_test.go | 16 +++- chart/lang.go | 112 ++++++++++++++++++++++++ tests/charts/lang.chart.json | 100 +++++++++++++++++++++ tests/charts/service/compare.chart.json | 2 +- tests/langs/zh-hk/charts/lang.yml | 10 +++ 6 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 chart/lang.go create mode 100644 tests/charts/lang.chart.json create mode 100644 tests/langs/zh-hk/charts/lang.yml diff --git a/chart/chart.go b/chart/chart.go index 4553607b..e0714152 100644 --- a/chart/chart.go +++ b/chart/chart.go @@ -6,6 +6,7 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/yaoapp/gou" + "github.com/yaoapp/gou/lang" "github.com/yaoapp/kun/exception" "github.com/yaoapp/kun/log" "github.com/yaoapp/yao/config" @@ -75,6 +76,12 @@ func LoadChart(source []byte, name string) (*Chart, error) { chart.Prepare() chart.SetupAPIs() Charts[name] = chart + + // Apply a language pack + if lang.Default != nil { + lang.Default.Apply(Charts[name]) + } + return chart, nil } diff --git a/chart/chart_test.go b/chart/chart_test.go index 6fcd1b15..afed79f0 100644 --- a/chart/chart_test.go +++ b/chart/chart_test.go @@ -1,16 +1,22 @@ package chart import ( + "os" "testing" "github.com/stretchr/testify/assert" "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/lang" "github.com/yaoapp/yao/model" "github.com/yaoapp/yao/query" "github.com/yaoapp/yao/share" ) func TestLoad(t *testing.T) { + + os.Setenv("YAO_LANG", "zh-hk") + lang.Load(config.Conf) + share.DBConnect(config.Conf.DB) model.Load(config.Conf) query.Load(config.Conf) @@ -25,5 +31,13 @@ func check(t *testing.T) { for key := range Charts { keys = append(keys, key) } - assert.Equal(t, 2, len(keys)) + assert.Equal(t, 3, len(keys)) + + lang := Charts["lang"] + output := lang.Output.(map[string]interface{}) + assert.Equal(t, "{{$in}}", output["參數"]) + + filters := lang.Page.Layout["filters"].([]interface{}) + begin := filters[0].(map[string]interface{}) + assert.Equal(t, "開始時間", begin["name"]) } diff --git a/chart/lang.go b/chart/lang.go new file mode 100644 index 00000000..68c4cd30 --- /dev/null +++ b/chart/lang.go @@ -0,0 +1,112 @@ +package chart + +// Lang for applying a language pack +func (chart *Chart) Lang(trans func(widget string, inst string, value *string) bool) { + inst := chart.Flow.Name + widget := "chart" + + trans(widget, inst, &chart.Name) + trans(widget, inst, &chart.Label) + trans(widget, inst, &chart.Description) + trans(widget, inst, &chart.Page.Primary) + transMap(widget, inst, chart.Page.Layout, trans) + chart.Output = transAny(widget, inst, chart.Output, trans) +} + +func transAny(widget string, inst string, input interface{}, trans func(widget string, inst string, value *string) bool) interface{} { + switch input.(type) { + case []interface{}: + values := input.([]interface{}) + transArr(widget, inst, values, trans) + input = values + break + + case map[string]interface{}: + values := input.(map[string]interface{}) + for name, value := range values { + new := name + newValue := value + + switch value.(type) { + case string: + val := value.(string) + trans(widget, inst, &val) + newValue = val + break + + case []interface{}: + vals := value.([]interface{}) + transArr(widget, inst, vals, trans) + newValue = vals + break + + case map[string]interface{}: + vals := value.(map[string]interface{}) + transMap(widget, inst, vals, trans) + newValue = vals + break + } + + trans(widget, inst, &new) + delete(values, name) + values[new] = newValue + } + input = values + break + } + + return input +} + +func transMap(widget string, inst string, values map[string]interface{}, trans func(widget string, inst string, value *string) bool) { + for key, value := range values { + + switch value.(type) { + + case string: + v := value.(string) + trans(widget, inst, &v) + values[key] = v + break + + case []interface{}: + v := value.([]interface{}) + transArr(widget, inst, v, trans) + values[key] = v + break + + case map[string]interface{}: + v := value.(map[string]interface{}) + transMap(widget, inst, v, trans) + values[key] = v + break + } + + } +} + +func transArr(widget string, inst string, values []interface{}, trans func(widget string, inst string, value *string) bool) { + for key, value := range values { + switch value.(type) { + + case string: + v := value.(string) + trans(widget, inst, &v) + values[key] = v + break + + case []interface{}: + v := value.([]interface{}) + transArr(widget, inst, v, trans) + values[key] = v + break + + case map[string]interface{}: + v := value.(map[string]interface{}) + transMap(widget, inst, v, trans) + values[key] = v + break + } + + } +} diff --git a/tests/charts/lang.chart.json b/tests/charts/lang.chart.json new file mode 100644 index 00000000..f2553516 --- /dev/null +++ b/tests/charts/lang.chart.json @@ -0,0 +1,100 @@ +{ + "label": "::Demo", + "version": "1.0.0", + "description": "::Demo", + "nodes": [ + { + "name": "行业", + "engine": "xiang", + "query": { + "select": [ + "city", + ":COUNT(id) as 数量", + "industries[*](string 50) as industry" + ], + "from": "$service", + "wheres": [ + { "field": "created_at", ">": "?:$from.0" }, + { "field": "created_at", "<": "?:$to" } + ], + "orders": "数量 desc", + "limit": 100 + } + }, + { + "name": "计费", + "engine": "xiang", + "query": { + "select": ["city", ":COUNT(id) as 数量", "price_options[*] as option"], + "from": "$service", + "wheres": [ + { "field": "created_at", ">": "?:$from.0" }, + { "field": "created_at", "<": "?:$to" } + ], + "orders": "数量 desc", + "limit": 100 + } + }, + { + "name": "合并结果", + "process": "xiang.helper.ArrayPluck", + "args": [ + ["城市", "行业", "计费"], + { + "行业": { "key": "city", "value": "数量", "items": "{{$res.行业}}" }, + "计费": { "key": "city", "value": "数量", "items": "{{$res.计费}}" } + } + ] + } + ], + "output": { + "::Merge": "{{$res.合并结果}}", + "::Billing": "{{$res.计费}}", + "::Industry": "{{$res.行业}}", + "::Parameter": "{{$in}}" + }, + "apis": { + "data": { + "disable": false, + "guard": "-", + "default": [{ "from": "1980-01-02", "to": "2050-12-31" }] + }, + "setting": { "disable": false, "guard": "-" } + }, + "filters": { + "::Start": { + "label": "::Start", + "bind": "from", + "input": { + "type": "date", + "props": { + "placeholder": "::Please select a start time" + } + } + }, + "::End": { + "label": "::End", + "bind": "to", + "input": { + "type": "date", + "props": { + "placeholder": "::Please select an end time" + } + } + } + }, + "page": { + "primary": "::City", + "layout": { + "filters": [ + { "name": "::Start", "width": 6 }, + { "name": "::End", "width": 6 } + ], + "charts": [ + { "type": "line", "props": {} }, + { "type": "bar", "props": {} } + ] + }, + "actions": {} + } +} diff --git a/tests/charts/service/compare.chart.json b/tests/charts/service/compare.chart.json index 96557046..0c66d6fb 100644 --- a/tests/charts/service/compare.chart.json +++ b/tests/charts/service/compare.chart.json @@ -7,7 +7,7 @@ "name": "行业", "engine": "xiang", "query": { - "debug": true, + "debug": false, "select": [ "city", ":COUNT(id) as 数量", diff --git a/tests/langs/zh-hk/charts/lang.yml b/tests/langs/zh-hk/charts/lang.yml new file mode 100644 index 00000000..0f0a4714 --- /dev/null +++ b/tests/langs/zh-hk/charts/lang.yml @@ -0,0 +1,10 @@ +Start: 開始時間 +End: 結束時間 +City: 城市 +Please select a start time: 請選擇開始時間 +Please select an end time: 請選擇結束時間 +Industry: 行業 +Billing: 計費 +Merge Reulst: 合併結果 +Parameter: 參數 +Merge: 合併