[add] language pack support for chart
This commit is contained in:
parent
22d93f10d9
commit
850e4dacc5
6 changed files with 245 additions and 2 deletions
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
|
"github.com/yaoapp/gou/lang"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/kun/log"
|
"github.com/yaoapp/kun/log"
|
||||||
"github.com/yaoapp/yao/config"
|
"github.com/yaoapp/yao/config"
|
||||||
|
|
@ -75,6 +76,12 @@ func LoadChart(source []byte, name string) (*Chart, error) {
|
||||||
chart.Prepare()
|
chart.Prepare()
|
||||||
chart.SetupAPIs()
|
chart.SetupAPIs()
|
||||||
Charts[name] = chart
|
Charts[name] = chart
|
||||||
|
|
||||||
|
// Apply a language pack
|
||||||
|
if lang.Default != nil {
|
||||||
|
lang.Default.Apply(Charts[name])
|
||||||
|
}
|
||||||
|
|
||||||
return chart, nil
|
return chart, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
package chart
|
package chart
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/yaoapp/yao/config"
|
"github.com/yaoapp/yao/config"
|
||||||
|
"github.com/yaoapp/yao/lang"
|
||||||
"github.com/yaoapp/yao/model"
|
"github.com/yaoapp/yao/model"
|
||||||
"github.com/yaoapp/yao/query"
|
"github.com/yaoapp/yao/query"
|
||||||
"github.com/yaoapp/yao/share"
|
"github.com/yaoapp/yao/share"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoad(t *testing.T) {
|
func TestLoad(t *testing.T) {
|
||||||
|
|
||||||
|
os.Setenv("YAO_LANG", "zh-hk")
|
||||||
|
lang.Load(config.Conf)
|
||||||
|
|
||||||
share.DBConnect(config.Conf.DB)
|
share.DBConnect(config.Conf.DB)
|
||||||
model.Load(config.Conf)
|
model.Load(config.Conf)
|
||||||
query.Load(config.Conf)
|
query.Load(config.Conf)
|
||||||
|
|
@ -25,5 +31,13 @@ func check(t *testing.T) {
|
||||||
for key := range Charts {
|
for key := range Charts {
|
||||||
keys = append(keys, key)
|
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"])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
112
chart/lang.go
Normal file
112
chart/lang.go
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
100
tests/charts/lang.chart.json
Normal file
100
tests/charts/lang.chart.json
Normal file
|
|
@ -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": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"name": "行业",
|
"name": "行业",
|
||||||
"engine": "xiang",
|
"engine": "xiang",
|
||||||
"query": {
|
"query": {
|
||||||
"debug": true,
|
"debug": false,
|
||||||
"select": [
|
"select": [
|
||||||
"city",
|
"city",
|
||||||
":COUNT(id) as 数量",
|
":COUNT(id) as 数量",
|
||||||
|
|
|
||||||
10
tests/langs/zh-hk/charts/lang.yml
Normal file
10
tests/langs/zh-hk/charts/lang.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
Start: 開始時間
|
||||||
|
End: 結束時間
|
||||||
|
City: 城市
|
||||||
|
Please select a start time: 請選擇開始時間
|
||||||
|
Please select an end time: 請選擇結束時間
|
||||||
|
Industry: 行業
|
||||||
|
Billing: 計費
|
||||||
|
Merge Reulst: 合併結果
|
||||||
|
Parameter: 參數
|
||||||
|
Merge: 合併
|
||||||
Loading…
Add table
Reference in a new issue