From 85466c7ee1ce5299ed67943a42ee7c8f10fef3ae Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 11 Mar 2016 17:04:26 +0100 Subject: [PATCH 01/33] fix(plugins): fixes broken link --- public/app/features/plugins/plugin_edit_ctrl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/plugins/plugin_edit_ctrl.ts b/public/app/features/plugins/plugin_edit_ctrl.ts index 2d4362835d4..71beb9d0268 100644 --- a/public/app/features/plugins/plugin_edit_ctrl.ts +++ b/public/app/features/plugins/plugin_edit_ctrl.ts @@ -78,7 +78,7 @@ export class PluginEditCtrl { secureJsonData: self.model.secureJsonData, }, {}); - return self.backendSrv.post(`/api/org/plugins/${self.pluginId}/settings`, updateCmd); + return self.backendSrv.post(`/api/plugins/${self.pluginId}/settings`, updateCmd); }); // if set, performt he postUpdate hook. If a promise is returned it will block From c1e4d0590c40206c28a72fe52b647d5f02a2f1e3 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 11 Mar 2016 17:13:35 +0100 Subject: [PATCH 02/33] fix(plugins): fixes broken plugin link --- public/app/features/plugins/plugin_page_ctrl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/plugins/plugin_page_ctrl.ts b/public/app/features/plugins/plugin_page_ctrl.ts index 9157f14202e..6a840717a80 100644 --- a/public/app/features/plugins/plugin_page_ctrl.ts +++ b/public/app/features/plugins/plugin_page_ctrl.ts @@ -11,7 +11,7 @@ export class AppPageCtrl { /** @ngInject */ constructor(private backendSrv, private $routeParams: any, private $rootScope) { this.pluginId = $routeParams.pluginId; - this.backendSrv.get(`/api/org/plugins/${this.pluginId}/settings`).then(app => { + this.backendSrv.get(`/api/plugins/${this.pluginId}/settings`).then(app => { this.appModel = app; this.page = _.findWhere(app.pages, {slug: this.$routeParams.slug}); if (!this.page) { From c5a817194a0a669434516e7c942b55721dc1c368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 11 Mar 2016 17:31:57 +0100 Subject: [PATCH 03/33] more work on dashboard importing and templating --- pkg/api/api.go | 2 +- pkg/api/dtos/plugins.go | 10 +- pkg/api/plugins.go | 4 +- pkg/components/dynmap/dynmap.go | 813 ++++++++++++++++++ pkg/components/dynmap/dynmap_test.go | 313 +++++++ pkg/plugins/dashboard_importer.go | 130 +++ pkg/plugins/dashboard_importer_test.go | 81 ++ pkg/plugins/dashboard_installer.go | 57 -- .../plugins/import_list/import_list.ts | 15 +- .../features/plugins/partials/ds_edit.html | 2 +- .../graphite/dashboards/carbon_stats.json | 1 + tests/test-app/dashboards/connections.json | 21 +- 12 files changed, 1380 insertions(+), 69 deletions(-) create mode 100644 pkg/components/dynmap/dynmap.go create mode 100644 pkg/components/dynmap/dynmap_test.go create mode 100644 pkg/plugins/dashboard_importer.go create mode 100644 pkg/plugins/dashboard_importer_test.go delete mode 100644 pkg/plugins/dashboard_installer.go diff --git a/pkg/api/api.go b/pkg/api/api.go index d4bb22149f8..c350b278679 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -176,7 +176,7 @@ func Register(r *macaron.Macaron) { r.Get("/", wrap(GetPluginList)) r.Get("/dashboards/:pluginId", wrap(GetPluginDashboards)) - r.Post("/dashboards/install", bind(dtos.InstallPluginDashboardCmd{}), wrap(InstallPluginDashboard)) + r.Post("/dashboards/import", bind(dtos.ImportDashboardCommand{}), wrap(ImportDashboard)) r.Get("/:pluginId/settings", wrap(GetPluginSettingById)) r.Post("/:pluginId/settings", bind(m.UpdatePluginSettingCmd{}), wrap(UpdatePluginSetting)) diff --git a/pkg/api/dtos/plugins.go b/pkg/api/dtos/plugins.go index 5f3dac76296..7008c939aef 100644 --- a/pkg/api/dtos/plugins.go +++ b/pkg/api/dtos/plugins.go @@ -26,9 +26,9 @@ type PluginListItem struct { Info *plugins.PluginInfo `json:"info"` } -type InstallPluginDashboardCmd struct { - PluginId string `json:"pluginId"` - Path string `json:"path"` - Reinstall bool `json:"reinstall"` - Inputs map[string]interface{} `json:"inputs"` +type ImportDashboardCommand struct { + PluginId string `json:"pluginId"` + Path string `json:"path"` + Reinstall bool `json:"reinstall"` + Inputs []plugins.ImportDashboardInput `json:"inputs"` } diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index 1ba0dde6c9f..2eb27c3c8ed 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -122,9 +122,9 @@ func GetPluginDashboards(c *middleware.Context) Response { } } -func InstallPluginDashboard(c *middleware.Context, apiCmd dtos.InstallPluginDashboardCmd) Response { +func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand) Response { - cmd := plugins.InstallPluginDashboardCommand{ + cmd := plugins.ImportDashboardCommand{ OrgId: c.OrgId, UserId: c.UserId, PluginId: apiCmd.PluginId, diff --git a/pkg/components/dynmap/dynmap.go b/pkg/components/dynmap/dynmap.go new file mode 100644 index 00000000000..bd7c8627bf0 --- /dev/null +++ b/pkg/components/dynmap/dynmap.go @@ -0,0 +1,813 @@ +// uses code from https://github.com/antonholmquist/jason/blob/master/jason.go +// MIT Licence + +package dynmap + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "strings" +) + +// Error values returned when validation functions fail +var ( + ErrNotNull = errors.New("is not null") + ErrNotArray = errors.New("Not an array") + ErrNotNumber = errors.New("not a number") + ErrNotBool = errors.New("no bool") + ErrNotObject = errors.New("not an object") + ErrNotObjectArray = errors.New("not an object array") + ErrNotString = errors.New("not a string") +) + +type KeyNotFoundError struct { + Key string +} + +func (k KeyNotFoundError) Error() string { + if k.Key != "" { + return fmt.Sprintf("key '%s' not found", k.Key) + } + + return "key not found" +} + +// Value represents an arbitrary JSON value. +// It may contain a bool, number, string, object, array or null. +type Value struct { + data interface{} + exists bool // Used to separate nil and non-existing values +} + +// Object represents an object JSON object. +// It inherets from Value but with an additional method to access +// a map representation of it's content. It's useful when iterating. +type Object struct { + Value + m map[string]*Value + valid bool +} + +// Returns the golang map. +// Needed when iterating through the values of the object. +func (v *Object) Map() map[string]*Value { + return v.m +} + +func NewFromMap(data map[string]interface{}) *Object { + val := &Value{data: data, exists: true} + obj, _ := val.Object() + return obj +} + +func NewObject() *Object { + val := &Value{data: make(map[string]interface{}), exists: true} + obj, _ := val.Object() + return obj +} + +// Creates a new value from an io.reader. +// Returns an error if the reader does not contain valid json. +// Useful for parsing the body of a net/http response. +// Example: NewFromReader(res.Body) +func NewValueFromReader(reader io.Reader) (*Value, error) { + j := new(Value) + d := json.NewDecoder(reader) + d.UseNumber() + err := d.Decode(&j.data) + return j, err +} + +// Creates a new value from bytes. +// Returns an error if the bytes are not valid json. +func NewValueFromBytes(b []byte) (*Value, error) { + r := bytes.NewReader(b) + return NewValueFromReader(r) +} + +func objectFromValue(v *Value, err error) (*Object, error) { + if err != nil { + return nil, err + } + + o, err := v.Object() + + if err != nil { + return nil, err + } + + return o, nil +} + +func NewObjectFromBytes(b []byte) (*Object, error) { + return objectFromValue(NewValueFromBytes(b)) +} + +func NewObjectFromReader(reader io.Reader) (*Object, error) { + return objectFromValue(NewValueFromReader(reader)) +} + +// Marshal into bytes. +func (v *Value) Marshal() ([]byte, error) { + return json.Marshal(v.data) +} + +// Get the interyling data as interface +func (v *Value) Interface() interface{} { + return v.data +} + +// Private Get +func (v *Value) get(key string) (*Value, error) { + + // Assume this is an object + obj, err := v.Object() + + if err == nil { + child, ok := obj.Map()[key] + if ok { + return child, nil + } else { + return nil, KeyNotFoundError{key} + } + } + + return nil, err +} + +// Private get path +func (v *Value) getPath(keys []string) (*Value, error) { + current := v + var err error + for _, key := range keys { + current, err = current.get(key) + + if err != nil { + return nil, err + } + } + return current, nil +} + +// Gets the value at key path. +// Returns error if the value does not exist. +// Consider using the more specific Get(..) methods instead. +// Example: +// value, err := GetValue("address", "street") +func (v *Object) GetValue(keys ...string) (*Value, error) { + return v.getPath(keys) +} + +// Gets the value at key path and attempts to typecast the value into an object. +// Returns error if the value is not a json object. +// Example: +// object, err := GetObject("person", "address") +func (v *Object) GetObject(keys ...string) (*Object, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + obj, err := child.Object() + + if err != nil { + return nil, err + } else { + return obj, nil + } + + } +} + +// Gets the value at key path and attempts to typecast the value into a string. +// Returns error if the value is not a json string. +// Example: +// string, err := GetString("address", "street") +func (v *Object) GetString(keys ...string) (string, error) { + child, err := v.getPath(keys) + + if err != nil { + return "", err + } else { + return child.String() + } +} + +func (v *Object) MustGetString(path string, def string) string { + keys := strings.Split(path, ".") + if str, err := v.GetString(keys...); err != nil { + return def + } else { + return str + } +} + +// Gets the value at key path and attempts to typecast the value into null. +// Returns error if the value is not json null. +// Example: +// err := GetNull("address", "street") +func (v *Object) GetNull(keys ...string) error { + child, err := v.getPath(keys) + + if err != nil { + return err + } + + return child.Null() +} + +// Gets the value at key path and attempts to typecast the value into a number. +// Returns error if the value is not a json number. +// Example: +// n, err := GetNumber("address", "street_number") +func (v *Object) GetNumber(keys ...string) (json.Number, error) { + child, err := v.getPath(keys) + + if err != nil { + return "", err + } else { + + n, err := child.Number() + + if err != nil { + return "", err + } else { + return n, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into a float64. +// Returns error if the value is not a json number. +// Example: +// n, err := GetNumber("address", "street_number") +func (v *Object) GetFloat64(keys ...string) (float64, error) { + child, err := v.getPath(keys) + + if err != nil { + return 0, err + } else { + + n, err := child.Float64() + + if err != nil { + return 0, err + } else { + return n, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into a float64. +// Returns error if the value is not a json number. +// Example: +// n, err := GetNumber("address", "street_number") +func (v *Object) GetInt64(keys ...string) (int64, error) { + child, err := v.getPath(keys) + + if err != nil { + return 0, err + } else { + + n, err := child.Int64() + + if err != nil { + return 0, err + } else { + return n, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into a float64. +// Returns error if the value is not a json number. +// Example: +// v, err := GetInterface("address", "anything") +func (v *Object) GetInterface(keys ...string) (interface{}, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + return child.Interface(), nil + } +} + +// Gets the value at key path and attempts to typecast the value into a bool. +// Returns error if the value is not a json boolean. +// Example: +// married, err := GetBoolean("person", "married") +func (v *Object) GetBoolean(keys ...string) (bool, error) { + child, err := v.getPath(keys) + + if err != nil { + return false, err + } + + return child.Boolean() +} + +// Gets the value at key path and attempts to typecast the value into an array. +// Returns error if the value is not a json array. +// Consider using the more specific GetArray() since it may reduce later type casts. +// Example: +// friends, err := GetValueArray("person", "friends") +// for i, friend := range friends { +// ... // friend will be of type Value here +// } +func (v *Object) GetValueArray(keys ...string) ([]*Value, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + return child.Array() + + } +} + +// Gets the value at key path and attempts to typecast the value into an array of objects. +// Returns error if the value is not a json array or if any of the contained objects are not objects. +// Example: +// friends, err := GetObjectArray("person", "friends") +// for i, friend := range friends { +// ... // friend will be of type Object here +// } +func (v *Object) GetObjectArray(keys ...string) ([]*Object, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]*Object, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem. + Object() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of string. +// Returns error if the value is not a json array or if any of the contained objects are not strings. +// Gets the value at key path and attempts to typecast the value into an array of objects. +// Returns error if the value is not a json array or if any of the contained objects are not objects. +// Example: +// friendNames, err := GetStringArray("person", "friend_names") +// for i, friendName := range friendNames { +// ... // friendName will be of type string here +// } +func (v *Object) GetStringArray(keys ...string) ([]string, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]string, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem.String() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of numbers. +// Returns error if the value is not a json array or if any of the contained objects are not numbers. +// Example: +// friendAges, err := GetNumberArray("person", "friend_ages") +// for i, friendAge := range friendAges { +// ... // friendAge will be of type float64 here +// } +func (v *Object) GetNumberArray(keys ...string) ([]json.Number, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]json.Number, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem.Number() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of floats. +// Returns error if the value is not a json array or if any of the contained objects are not numbers. +func (v *Object) GetFloat64Array(keys ...string) ([]float64, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]float64, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem.Float64() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of ints. +// Returns error if the value is not a json array or if any of the contained objects are not numbers. +func (v *Object) GetInt64Array(keys ...string) ([]int64, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]int64, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem.Int64() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of bools. +// Returns error if the value is not a json array or if any of the contained objects are not booleans. +func (v *Object) GetBooleanArray(keys ...string) ([]bool, error) { + child, err := v.getPath(keys) + + if err != nil { + return nil, err + } else { + + array, err := child.Array() + + if err != nil { + return nil, err + } else { + + typedArray := make([]bool, len(array)) + + for index, arrayItem := range array { + typedArrayItem, err := arrayItem.Boolean() + + if err != nil { + return nil, err + } else { + typedArray[index] = typedArrayItem + } + + } + return typedArray, nil + } + } +} + +// Gets the value at key path and attempts to typecast the value into an array of nulls. +// Returns length, or an error if the value is not a json array or if any of the contained objects are not nulls. +func (v *Object) GetNullArray(keys ...string) (int64, error) { + child, err := v.getPath(keys) + + if err != nil { + return 0, err + } else { + + array, err := child.Array() + + if err != nil { + return 0, err + } else { + + var length int64 = 0 + + for _, arrayItem := range array { + err := arrayItem.Null() + + if err != nil { + return 0, err + } else { + length++ + } + + } + return length, nil + } + } +} + +// Returns an error if the value is not actually null +func (v *Value) Null() error { + var valid bool + + // Check the type of this data + switch v.data.(type) { + case nil: + valid = v.exists // Valid only if j also exists, since other values could possibly also be nil + break + } + + if valid { + return nil + } + + return ErrNotNull + +} + +// Attempts to typecast the current value into an array. +// Returns error if the current value is not a json array. +// Example: +// friendsArray, err := friendsValue.Array() +func (v *Value) Array() ([]*Value, error) { + var valid bool + + // Check the type of this data + switch v.data.(type) { + case []interface{}: + valid = true + break + } + + // Unsure if this is a good way to use slices, it's probably not + var slice []*Value + + if valid { + + for _, element := range v.data.([]interface{}) { + child := Value{element, true} + slice = append(slice, &child) + } + + return slice, nil + } + + return slice, ErrNotArray + +} + +// Attempts to typecast the current value into a number. +// Returns error if the current value is not a json number. +// Example: +// ageNumber, err := ageValue.Number() +func (v *Value) Number() (json.Number, error) { + var valid bool + + // Check the type of this data + switch v.data.(type) { + case json.Number: + valid = true + break + } + + if valid { + return v.data.(json.Number), nil + } + + return "", ErrNotNumber +} + +// Attempts to typecast the current value into a float64. +// Returns error if the current value is not a json number. +// Example: +// percentage, err := v.Float64() +func (v *Value) Float64() (float64, error) { + n, err := v.Number() + + if err != nil { + return 0, err + } + + return n.Float64() +} + +// Attempts to typecast the current value into a int64. +// Returns error if the current value is not a json number. +// Example: +// id, err := v.Int64() +func (v *Value) Int64() (int64, error) { + n, err := v.Number() + + if err != nil { + return 0, err + } + + return n.Int64() +} + +// Attempts to typecast the current value into a bool. +// Returns error if the current value is not a json boolean. +// Example: +// marriedBool, err := marriedValue.Boolean() +func (v *Value) Boolean() (bool, error) { + var valid bool + + // Check the type of this data + switch v.data.(type) { + case bool: + valid = true + break + } + + if valid { + return v.data.(bool), nil + } + + return false, ErrNotBool +} + +// Attempts to typecast the current value into an object. +// Returns error if the current value is not a json object. +// Example: +// friendObject, err := friendValue.Object() +func (v *Value) Object() (*Object, error) { + + var valid bool + + // Check the type of this data + switch v.data.(type) { + case map[string]interface{}: + valid = true + break + } + + if valid { + obj := new(Object) + obj.valid = valid + + m := make(map[string]*Value) + + if valid { + for key, element := range v.data.(map[string]interface{}) { + m[key] = &Value{element, true} + + } + } + + obj.data = v.data + obj.m = m + + return obj, nil + } + + return nil, ErrNotObject +} + +// Attempts to typecast the current value into an object arrau. +// Returns error if the current value is not an array of json objects +// Example: +// friendObjects, err := friendValues.ObjectArray() +func (v *Value) ObjectArray() ([]*Object, error) { + + var valid bool + + // Check the type of this data + switch v.data.(type) { + case []interface{}: + valid = true + break + } + + // Unsure if this is a good way to use slices, it's probably not + var slice []*Object + + if valid { + + for _, element := range v.data.([]interface{}) { + childValue := Value{element, true} + childObject, err := childValue.Object() + + if err != nil { + return nil, ErrNotObjectArray + } + slice = append(slice, childObject) + } + + return slice, nil + } + + return nil, ErrNotObjectArray + +} + +// Attempts to typecast the current value into a string. +// Returns error if the current value is not a json string +// Example: +// nameObject, err := nameValue.String() +func (v *Value) String() (string, error) { + var valid bool + + // Check the type of this data + switch v.data.(type) { + case string: + valid = true + break + } + + if valid { + return v.data.(string), nil + } + + return "", ErrNotString +} + +// Returns the value a json formatted string. +// Note: The method named String() is used by golang's log method for logging. +// Example: +func (v *Object) String() string { + + f, err := json.Marshal(v.data) + if err != nil { + return err.Error() + } + + return string(f) + +} + +func (v *Object) SetValue(key string, value interface{}) *Value { + data := v.Interface().(map[string]interface{}) + data[key] = value + + return &Value{ + data: value, + exists: true, + } +} diff --git a/pkg/components/dynmap/dynmap_test.go b/pkg/components/dynmap/dynmap_test.go new file mode 100644 index 00000000000..cc002ea06e0 --- /dev/null +++ b/pkg/components/dynmap/dynmap_test.go @@ -0,0 +1,313 @@ +// uses code from https://github.com/antonholmquist/jason/blob/master/jason.go +// MIT Licence + +package dynmap + +import ( + "log" + "testing" + + . "github.com/smartystreets/goconvey/convey" +) + +type Assert struct { + T *testing.T +} + +func NewAssert(t *testing.T) *Assert { + return &Assert{ + T: t, + } +} + +func (assert *Assert) True(value bool, message string) { + if value == false { + log.Panicln("Assert: ", message) + } +} + +func TestFirst(t *testing.T) { + + assert := NewAssert(t) + + testJSON := `{ + "name": "anton", + "age": 29, + "nothing": null, + "true": true, + "false": false, + "list": [ + "first", + "second" + ], + "list2": [ + { + "street": "Street 42", + "city": "Stockholm" + }, + { + "street": "Street 42", + "city": "Stockholm" + } + ], + "address": { + "street": "Street 42", + "city": "Stockholm" + }, + "country": { + "name": "Sweden" + } + }` + + j, err := NewObjectFromBytes([]byte(testJSON)) + + a, err := j.GetObject("address") + assert.True(a != nil && err == nil, "failed to create json from string") + + assert.True(err == nil, "failed to create json from string") + + s, err := j.GetString("name") + assert.True(s == "anton" && err == nil, "name should be a string") + + s = j.MustGetString("name", "fallback") + assert.True(s == "anton", "must get string") + + s = j.MustGetString("adsasdas", "fallback") + assert.True(s == "fallback", "must get string return fallback") + + s, err = j.GetString("name") + assert.True(s == "anton" && err == nil, "name shoud match") + + s, err = j.GetString("address", "street") + assert.True(s == "Street 42" && err == nil, "street shoud match") + //log.Println("s: ", s.String()) + + _, err = j.GetNumber("age") + assert.True(err == nil, "age should be a number") + + n, err := j.GetInt64("age") + assert.True(n == 29 && err == nil, "age mismatch") + + ageInterface, err := j.GetInterface("age") + assert.True(ageInterface != nil, "should be defined") + assert.True(err == nil, "age interface error") + + invalidInterface, err := j.GetInterface("not_existing") + assert.True(invalidInterface == nil, "should not give error here") + assert.True(err != nil, "should give error here") + + age, err := j.GetValue("age") + assert.True(age != nil && err == nil, "age should exist") + + age2, err := j.GetValue("age2") + assert.True(age2 == nil && err != nil, "age2 should not exist") + + address, err := j.GetObject("address") + assert.True(address != nil && err == nil, "address should be an object") + + //log.Println("address: ", address) + + s, err = address.GetString("street") + + addressAsString, err := j.GetString("address") + assert.True(addressAsString == "" && err != nil, "address should not be an string") + + s, err = j.GetString("address", "street") + assert.True(s == "Street 42" && err == nil, "street mismatching") + + s, err = j.GetString("address", "name2") + assert.True(s == "" && err != nil, "nonexistent string fail") + + b, err := j.GetBoolean("true") + assert.True(b == true && err == nil, "bool true test") + + b, err = j.GetBoolean("false") + assert.True(b == false && err == nil, "bool false test") + + b, err = j.GetBoolean("invalid_field") + assert.True(b == false && err != nil, "bool invalid test") + + list, err := j.GetValueArray("list") + assert.True(list != nil && err == nil, "list should be an array") + + list2, err := j.GetValueArray("list2") + assert.True(list2 != nil && err == nil, "list2 should be an array") + + list2Array, err := j.GetValueArray("list2") + assert.True(err == nil, "List2 should not return error on AsArray") + assert.True(len(list2Array) == 2, "List2 should should have length 2") + + list2Value, err := j.GetValue("list2") + assert.True(err == nil, "List2 should not return error on value") + + list2ObjectArray, err := list2Value.ObjectArray() + assert.True(err == nil, "list2Value should not return error on ObjectArray") + assert.True(len(list2ObjectArray) == 2, "list2ObjectArray should should have length 2") + + for _, elementValue := range list2Array { + //assert.True(element.IsObject() == true, "first fail") + + element, err := elementValue.Object() + + s, err = element.GetString("street") + assert.True(s == "Street 42" && err == nil, "second fail") + } + + obj, err := j.GetObject("country") + assert.True(obj != nil && err == nil, "country should not return error on AsObject") + for key, value := range obj.Map() { + + assert.True(key == "name", "country name key incorrect") + + s, err = value.String() + assert.True(s == "Sweden" && err == nil, "country name should be Sweden") + } +} + +func TestSecond(t *testing.T) { + json := ` + { + "data": [ + { + "id": "X999_Y999", + "from": { + "name": "Tom Brady", "id": "X12" + }, + "message": "Looking forward to 2010!", + "actions": [ + { + "name": "Comment", + "link": "http://www.facebook.com/X999/posts/Y999" + }, + { + "name": "Like", + "link": "http://www.facebook.com/X999/posts/Y999" + } + ], + "type": "status", + "created_time": "2010-08-02T21:27:44+0000", + "updated_time": "2010-08-02T21:27:44+0000" + }, + { + "id": "X998_Y998", + "from": { + "name": "Peyton Manning", "id": "X18" + }, + "message": "Where's my contract?", + "actions": [ + { + "name": "Comment", + "link": "http://www.facebook.com/X998/posts/Y998" + }, + { + "name": "Like", + "link": "http://www.facebook.com/X998/posts/Y998" + } + ], + "type": "status", + "created_time": "2010-08-02T21:27:44+0000", + "updated_time": "2010-08-02T21:27:44+0000" + } + ] + }` + + assert := NewAssert(t) + j, err := NewObjectFromBytes([]byte(json)) + + assert.True(j != nil && err == nil, "failed to parse json") + + dataObject, err := j.GetObject("data") + assert.True(dataObject == nil && err != nil, "data should not be an object") + + dataArray, err := j.GetObjectArray("data") + assert.True(dataArray != nil && err == nil, "data should be an object array") + + for index, dataItem := range dataArray { + + if index == 0 { + id, err := dataItem.GetString("id") + assert.True(id == "X999_Y999" && err == nil, "item id mismatch") + + fromName, err := dataItem.GetString("from", "name") + assert.True(fromName == "Tom Brady" && err == nil, "fromName mismatch") + + actions, err := dataItem.GetObjectArray("actions") + + for index, action := range actions { + + if index == 1 { + name, err := action.GetString("name") + assert.True(name == "Like" && err == nil, "name mismatch") + + link, err := action.GetString("link") + assert.True(link == "http://www.facebook.com/X999/posts/Y999" && err == nil, "Like mismatch") + + } + + } + } else if index == 1 { + id, err := dataItem.GetString("id") + assert.True(id == "X998_Y998" && err == nil, "item id mismatch") + } + + } + +} + +func TestErrors(t *testing.T) { + json := ` + { + "string": "hello", + "number": 1, + "array": [1,2,3] + }` + + errstr := "expected an error getting %s, but got '%s'" + + j, err := NewObjectFromBytes([]byte(json)) + if err != nil { + t.Fatal("failed to parse json") + } + + if _, err = j.GetObject("string"); err != ErrNotObject { + t.Errorf(errstr, "object", err) + } + + if err = j.GetNull("string"); err != ErrNotNull { + t.Errorf(errstr, "null", err) + } + + if _, err = j.GetStringArray("string"); err != ErrNotArray { + t.Errorf(errstr, "array", err) + } + + if _, err = j.GetStringArray("array"); err != ErrNotString { + t.Errorf(errstr, "string array", err) + } + + if _, err = j.GetNumber("array"); err != ErrNotNumber { + t.Errorf(errstr, "number", err) + } + + if _, err = j.GetBoolean("array"); err != ErrNotBool { + t.Errorf(errstr, "boolean", err) + } + + if _, err = j.GetString("number"); err != ErrNotString { + t.Errorf(errstr, "string", err) + } + + _, err = j.GetString("not_found") + if e, ok := err.(KeyNotFoundError); !ok { + t.Errorf(errstr, "key not found error", e) + } + +} + +func TestWriting(t *testing.T) { + Convey("When writing", t, func() { + j, _ := NewObjectFromBytes([]byte(`{}`)) + j.SetValue("prop", "value") + So(j.MustGetString("prop", ""), ShouldEqual, "value") + }) +} diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go new file mode 100644 index 00000000000..a9ee7a6b46c --- /dev/null +++ b/pkg/plugins/dashboard_importer.go @@ -0,0 +1,130 @@ +package plugins + +import ( + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/components/dynmap" + "github.com/grafana/grafana/pkg/log" + m "github.com/grafana/grafana/pkg/models" +) + +type ImportDashboardCommand struct { + Path string `json:"string"` + Inputs []ImportDashboardInput `json:"inputs"` + + OrgId int64 `json:"-"` + UserId int64 `json:"-"` + PluginId string `json:"-"` + Result *PluginDashboardInfoDTO +} + +type ImportDashboardInput struct { + Type string `json:"type"` + PluginId string `json:"pluginId"` + Name string `json:"name"` + Value string `json:"value"` +} + +func init() { + bus.AddHandler("plugins", ImportDashboard) +} + +func ImportDashboard(cmd *ImportDashboardCommand) error { + plugin, exists := Plugins[cmd.PluginId] + + if !exists { + return PluginNotFoundError{cmd.PluginId} + } + + var dashboard *m.Dashboard + var err error + + if dashboard, err = loadPluginDashboard(plugin, cmd.Path); err != nil { + return err + } + + saveCmd := m.SaveDashboardCommand{ + Dashboard: dashboard.Data, + OrgId: cmd.OrgId, + UserId: cmd.UserId, + } + + if err := bus.Dispatch(&saveCmd); err != nil { + return err + } + + cmd.Result = &PluginDashboardInfoDTO{ + PluginId: cmd.PluginId, + Title: dashboard.Title, + Path: cmd.Path, + Revision: dashboard.GetString("revision", "1.0"), + InstalledUri: "db/" + saveCmd.Result.Slug, + InstalledRevision: dashboard.GetString("revision", "1.0"), + Installed: true, + } + + return nil +} + +type DashTemplateEvaluator struct { + template *dynmap.Object + inputs []ImportDashboardInput + variables map[string]string + result *dynmap.Object +} + +// func (this *DashTemplateEvaluator) getObject(path string) map[string]interface{} { +// if obj, exists := this.template[path]; exists { +// return obj.(map[string]interface{}) +// } +// return nil +// } + +func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Object) *ImportDashboardInput { + inputType, _ := varDef.GetString("type") + + for _, input := range this.inputs { + if inputType == input.Type && (input.Name == varName || input.Name == "*") { + return &input + } + } + + return nil +} + +func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) { + this.result = dynmap.NewObject() + this.variables = make(map[string]string) + + // check that we have all inputs we need + if requiredInputs, err := this.template.GetObject("__inputs"); err == nil { + for varName, value := range requiredInputs.Map() { + varDef, _ := value.Object() + input := this.findInput(varName, varDef) + this.variables[varName] = input.Value + } + } + + this.EvalObject(this.template, this.result) + return this.result, nil +} + +func (this *DashTemplateEvaluator) EvalObject(source *dynmap.Object, writer *dynmap.Object) { + + for key, value := range source.Map() { + if key == "__input" { + continue + } + + goValue := value.Interface() + switch goValue.(type) { + case string: + writer.SetValue(key, goValue) + case map[string]interface{}: + childSource, _ := value.Object() + childWriter, _ := writer.SetValue(key, map[string]interface{}{}).Object() + this.EvalObject(childSource, childWriter) + default: + log.Error(3, "Unknown json type key: %v , type: %v", key, goValue) + } + } +} diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go new file mode 100644 index 00000000000..90f4ba2847d --- /dev/null +++ b/pkg/plugins/dashboard_importer_test.go @@ -0,0 +1,81 @@ +package plugins + +import ( + "testing" + + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/components/dynmap" + m "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/setting" + . "github.com/smartystreets/goconvey/convey" + "gopkg.in/ini.v1" +) + +func TestDashboardImport(t *testing.T) { + + Convey("When importing plugin dashboard", t, func() { + setting.Cfg = ini.Empty() + sec, _ := setting.Cfg.NewSection("plugin.test-app") + sec.NewKey("path", "../../tests/test-app") + err := Init() + + So(err, ShouldBeNil) + + var importedDash *m.Dashboard + bus.AddHandler("test", func(cmd *m.SaveDashboardCommand) error { + importedDash = cmd.GetDashboardModel() + cmd.Result = importedDash + return nil + }) + + cmd := ImportDashboardCommand{ + PluginId: "test-app", + Path: "dashboards/connections.json", + OrgId: 1, + UserId: 1, + Inputs: []ImportDashboardInput{}, + } + + err = ImportDashboard(&cmd) + So(err, ShouldBeNil) + + Convey("should install dashboard", func() { + So(importedDash, ShouldNotBeNil) + rows := importedDash.Data["rows"].([]interface{}) + row1 := rows[0].(map[string]interface{}) + panels := row1["panels"].([]interface{}) + panel := panels[0].(map[string]interface{}) + + So(panel["datasource"], ShouldEqual, "graphite") + So(importedDash.Data["__inputs"], ShouldBeNil) + }) + }) + + Convey("When evaling dashboard template", t, func() { + template, _ := dynmap.NewObjectFromBytes([]byte(`{ + "__input": { + "graphite": { + "type": "datasource" + } + }, + "test": { + "prop": "$__graphite" + } + }`)) + + evaluator := &DashTemplateEvaluator{ + template: template, + inputs: []ImportDashboardInput{ + {Name: "*", Type: "datasource", Value: "my-server"}, + }, + } + + res, err := evaluator.Eval() + So(err, ShouldBeNil) + + Convey("should render template", func() { + So(res.MustGetString("test.prop", ""), ShouldEqual, "my-server") + }) + }) + +} diff --git a/pkg/plugins/dashboard_installer.go b/pkg/plugins/dashboard_installer.go deleted file mode 100644 index 279ab209989..00000000000 --- a/pkg/plugins/dashboard_installer.go +++ /dev/null @@ -1,57 +0,0 @@ -package plugins - -import ( - "github.com/grafana/grafana/pkg/bus" - m "github.com/grafana/grafana/pkg/models" -) - -type InstallPluginDashboardCommand struct { - Path string `json:"string"` - Inputs map[string]interface{} `json:"inputs"` - - OrgId int64 `json:"-"` - UserId int64 `json:"-"` - PluginId string `json:"-"` - Result *PluginDashboardInfoDTO -} - -func init() { - bus.AddHandler("plugins", InstallPluginDashboard) -} - -func InstallPluginDashboard(cmd *InstallPluginDashboardCommand) error { - plugin, exists := Plugins[cmd.PluginId] - - if !exists { - return PluginNotFoundError{cmd.PluginId} - } - - var dashboard *m.Dashboard - var err error - - if dashboard, err = loadPluginDashboard(plugin, cmd.Path); err != nil { - return err - } - - saveCmd := m.SaveDashboardCommand{ - Dashboard: dashboard.Data, - OrgId: cmd.OrgId, - UserId: cmd.UserId, - } - - if err := bus.Dispatch(&saveCmd); err != nil { - return err - } - - cmd.Result = &PluginDashboardInfoDTO{ - PluginId: cmd.PluginId, - Title: dashboard.Title, - Path: cmd.Path, - Revision: dashboard.GetString("revision", "1.0"), - InstalledUri: "db/" + saveCmd.Result.Slug, - InstalledRevision: dashboard.GetString("revision", "1.0"), - Installed: true, - } - - return nil -} diff --git a/public/app/features/plugins/import_list/import_list.ts b/public/app/features/plugins/import_list/import_list.ts index 62145623fa2..004fde69bd1 100644 --- a/public/app/features/plugins/import_list/import_list.ts +++ b/public/app/features/plugins/import_list/import_list.ts @@ -7,6 +7,7 @@ import coreModule from 'app/core/core_module'; export class DashImportListCtrl { dashboards: any[]; plugin: any; + datasource: any; constructor(private $http, private backendSrv, private $rootScope) { this.dashboards = []; @@ -21,9 +22,18 @@ export class DashImportListCtrl { pluginId: this.plugin.id, path: dash.path, reinstall: reinstall, - inputs: {} + inputs: [] }; + if (this.datasource) { + installCmd.inputs.push({ + name: '*', + type: 'datasource', + pluginId: this.datasource.type, + value: this.datasource.name + }); + } + this.backendSrv.post(`/api/plugins/dashboards/install`, installCmd).then(res => { this.$rootScope.appEvent('alert-success', ['Dashboard Installed', dash.title]); _.extend(dash, res); @@ -46,7 +56,8 @@ export function dashboardImportList() { bindToController: true, controllerAs: 'ctrl', scope: { - plugin: "=" + plugin: "=", + datasource: "=" } }; } diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index 46177d998cc..d519b78ae55 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -74,7 +74,7 @@
- +
diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json index ad2c32be759..e206d8be57d 100644 --- a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json +++ b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json @@ -2,6 +2,7 @@ "__inputs": { "graphite": { "type": "datasource", + "pluginId": "graphite", "description": "Graphite datasource" } }, diff --git a/tests/test-app/dashboards/connections.json b/tests/test-app/dashboards/connections.json index f1f62826f73..feb90cae71d 100644 --- a/tests/test-app/dashboards/connections.json +++ b/tests/test-app/dashboards/connections.json @@ -1,5 +1,24 @@ { + "__inputs": { + "graphite": { + "type": "datasource", + "pluginId": "graphite", + "description": "Graphite datasource" + } + }, + "title": "Nginx Connections", "revision": "1.5", - "schemaVersion": 11 + "schemaVersion": 11, + + "rows": [ + { + "panels": [ + { + "type": "graph", + "datasource": "$__graphite" + } + ] + } + ] } From 1f9f439acb1015307fe53e52202864d9b6c69e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 11 Mar 2016 23:28:33 +0100 Subject: [PATCH 04/33] lib(): added simplejson lib --- pkg/api/cloudwatch/metrics.go | 7 +- pkg/api/dtos/models.go | 31 +- pkg/api/frontendsettings.go | 2 +- pkg/components/dynmap/dynmap.go | 4 + pkg/components/simplejson/simplejson.go | 461 ++++++++++++++++++ pkg/components/simplejson/simplejson_go11.go | 91 ++++ pkg/components/simplejson/simplejson_test.go | 248 ++++++++++ pkg/models/datasource.go | 56 ++- pkg/plugins/dashboard_importer.go | 54 +- pkg/plugins/dashboard_importer_test.go | 16 +- public/app/features/plugins/ds_edit_ctrl.ts | 3 +- .../features/plugins/partials/ds_edit.html | 14 +- .../graphite/dashboards/carbon_stats.json | 2 +- 13 files changed, 921 insertions(+), 68 deletions(-) create mode 100644 pkg/components/simplejson/simplejson.go create mode 100644 pkg/components/simplejson/simplejson_go11.go create mode 100644 pkg/components/simplejson/simplejson_test.go diff --git a/pkg/api/cloudwatch/metrics.go b/pkg/api/cloudwatch/metrics.go index 54ab565bede..f5e5274a202 100644 --- a/pkg/api/cloudwatch/metrics.go +++ b/pkg/api/cloudwatch/metrics.go @@ -130,11 +130,14 @@ func handleGetNamespaces(req *cwRequest, c *middleware.Context) { for key := range metricsMap { keys = append(keys, key) } - if customMetricsNamespaces, ok := req.DataSource.JsonData["customMetricsNamespaces"].(string); ok { - for _, key := range strings.Split(customMetricsNamespaces, ",") { + + customNamespaces := req.DataSource.JsonData.Get("customMetricsNamespaces").MustString() + if customNamespaces != "" { + for _, key := range strings.Split(customNamespaces, ",") { keys = append(keys, key) } } + sort.Sort(sort.StringSlice(keys)) result := []interface{}{} diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index 36e51fdc28a..d5534ea6ed4 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" ) @@ -57,21 +58,21 @@ type DashboardFullWithMeta struct { } type DataSource struct { - Id int64 `json:"id"` - OrgId int64 `json:"orgId"` - Name string `json:"name"` - Type string `json:"type"` - Access m.DsAccess `json:"access"` - Url string `json:"url"` - Password string `json:"password"` - User string `json:"user"` - Database string `json:"database"` - BasicAuth bool `json:"basicAuth"` - BasicAuthUser string `json:"basicAuthUser"` - BasicAuthPassword string `json:"basicAuthPassword"` - WithCredentials bool `json:"withCredentials"` - IsDefault bool `json:"isDefault"` - JsonData map[string]interface{} `json:"jsonData,omitempty"` + Id int64 `json:"id"` + OrgId int64 `json:"orgId"` + Name string `json:"name"` + Type string `json:"type"` + Access m.DsAccess `json:"access"` + Url string `json:"url"` + Password string `json:"password"` + User string `json:"user"` + Database string `json:"database"` + BasicAuth bool `json:"basicAuth"` + BasicAuthUser string `json:"basicAuthUser"` + BasicAuthPassword string `json:"basicAuthPassword"` + WithCredentials bool `json:"withCredentials"` + IsDefault bool `json:"isDefault"` + JsonData *simplejson.Json `json:"jsonData,omitempty"` } type MetricQueryResultDto struct { diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 8c86f98220a..c84d7faccff 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -59,7 +59,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro defaultDatasource = ds.Name } - if len(ds.JsonData) > 0 { + if len(ds.JsonData.MustMap()) > 0 { dsMap["jsonData"] = ds.JsonData } diff --git a/pkg/components/dynmap/dynmap.go b/pkg/components/dynmap/dynmap.go index bd7c8627bf0..797694845cd 100644 --- a/pkg/components/dynmap/dynmap.go +++ b/pkg/components/dynmap/dynmap.go @@ -120,6 +120,10 @@ func (v *Value) Interface() interface{} { return v.data } +func (v *Value) StringMap() map[string]interface{} { + return v.data.(map[string]interface{}) +} + // Private Get func (v *Value) get(key string) (*Value, error) { diff --git a/pkg/components/simplejson/simplejson.go b/pkg/components/simplejson/simplejson.go new file mode 100644 index 00000000000..1ea8aa346aa --- /dev/null +++ b/pkg/components/simplejson/simplejson.go @@ -0,0 +1,461 @@ +package simplejson + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log" +) + +// returns the current implementation version +func Version() string { + return "0.5.0" +} + +type Json struct { + data interface{} +} + +func (j *Json) FromDB(data []byte) error { + j.data = make(map[string]interface{}) + + dec := json.NewDecoder(bytes.NewBuffer(data)) + dec.UseNumber() + return dec.Decode(&j.data) +} + +func (j *Json) ToDB() ([]byte, error) { + return j.Encode() +} + +// NewJson returns a pointer to a new `Json` object +// after unmarshaling `body` bytes +func NewJson(body []byte) (*Json, error) { + j := new(Json) + err := j.UnmarshalJSON(body) + if err != nil { + return nil, err + } + return j, nil +} + +// New returns a pointer to a new, empty `Json` object +func New() *Json { + return &Json{ + data: make(map[string]interface{}), + } +} + +// Interface returns the underlying data +func (j *Json) Interface() interface{} { + return j.data +} + +// Encode returns its marshaled data as `[]byte` +func (j *Json) Encode() ([]byte, error) { + return j.MarshalJSON() +} + +// EncodePretty returns its marshaled data as `[]byte` with indentation +func (j *Json) EncodePretty() ([]byte, error) { + return json.MarshalIndent(&j.data, "", " ") +} + +// Implements the json.Marshaler interface. +func (j *Json) MarshalJSON() ([]byte, error) { + fmt.Printf("MarshalJSON") + return json.Marshal(&j.data) +} + +// Set modifies `Json` map by `key` and `value` +// Useful for changing single key/value in a `Json` object easily. +func (j *Json) Set(key string, val interface{}) { + m, err := j.Map() + if err != nil { + return + } + m[key] = val +} + +// SetPath modifies `Json`, recursively checking/creating map keys for the supplied path, +// and then finally writing in the value +func (j *Json) SetPath(branch []string, val interface{}) { + if len(branch) == 0 { + j.data = val + return + } + + // in order to insert our branch, we need map[string]interface{} + if _, ok := (j.data).(map[string]interface{}); !ok { + // have to replace with something suitable + j.data = make(map[string]interface{}) + } + curr := j.data.(map[string]interface{}) + + for i := 0; i < len(branch)-1; i++ { + b := branch[i] + // key exists? + if _, ok := curr[b]; !ok { + n := make(map[string]interface{}) + curr[b] = n + curr = n + continue + } + + // make sure the value is the right sort of thing + if _, ok := curr[b].(map[string]interface{}); !ok { + // have to replace with something suitable + n := make(map[string]interface{}) + curr[b] = n + } + + curr = curr[b].(map[string]interface{}) + } + + // add remaining k/v + curr[branch[len(branch)-1]] = val +} + +// Del modifies `Json` map by deleting `key` if it is present. +func (j *Json) Del(key string) { + m, err := j.Map() + if err != nil { + return + } + delete(m, key) +} + +// Get returns a pointer to a new `Json` object +// for `key` in its `map` representation +// +// useful for chaining operations (to traverse a nested JSON): +// js.Get("top_level").Get("dict").Get("value").Int() +func (j *Json) Get(key string) *Json { + m, err := j.Map() + if err == nil { + if val, ok := m[key]; ok { + return &Json{val} + } + } + return &Json{nil} +} + +// GetPath searches for the item as specified by the branch +// without the need to deep dive using Get()'s. +// +// js.GetPath("top_level", "dict") +func (j *Json) GetPath(branch ...string) *Json { + jin := j + for _, p := range branch { + jin = jin.Get(p) + } + return jin +} + +// GetIndex returns a pointer to a new `Json` object +// for `index` in its `array` representation +// +// this is the analog to Get when accessing elements of +// a json array instead of a json object: +// js.Get("top_level").Get("array").GetIndex(1).Get("key").Int() +func (j *Json) GetIndex(index int) *Json { + a, err := j.Array() + if err == nil { + if len(a) > index { + return &Json{a[index]} + } + } + return &Json{nil} +} + +// CheckGet returns a pointer to a new `Json` object and +// a `bool` identifying success or failure +// +// useful for chained operations when success is important: +// if data, ok := js.Get("top_level").CheckGet("inner"); ok { +// log.Println(data) +// } +func (j *Json) CheckGet(key string) (*Json, bool) { + m, err := j.Map() + if err == nil { + if val, ok := m[key]; ok { + return &Json{val}, true + } + } + return nil, false +} + +// Map type asserts to `map` +func (j *Json) Map() (map[string]interface{}, error) { + if m, ok := (j.data).(map[string]interface{}); ok { + return m, nil + } + return nil, errors.New("type assertion to map[string]interface{} failed") +} + +// Array type asserts to an `array` +func (j *Json) Array() ([]interface{}, error) { + if a, ok := (j.data).([]interface{}); ok { + return a, nil + } + return nil, errors.New("type assertion to []interface{} failed") +} + +// Bool type asserts to `bool` +func (j *Json) Bool() (bool, error) { + if s, ok := (j.data).(bool); ok { + return s, nil + } + return false, errors.New("type assertion to bool failed") +} + +// String type asserts to `string` +func (j *Json) String() (string, error) { + if s, ok := (j.data).(string); ok { + return s, nil + } + return "", errors.New("type assertion to string failed") +} + +// Bytes type asserts to `[]byte` +func (j *Json) Bytes() ([]byte, error) { + if s, ok := (j.data).(string); ok { + return []byte(s), nil + } + return nil, errors.New("type assertion to []byte failed") +} + +// StringArray type asserts to an `array` of `string` +func (j *Json) StringArray() ([]string, error) { + arr, err := j.Array() + if err != nil { + return nil, err + } + retArr := make([]string, 0, len(arr)) + for _, a := range arr { + if a == nil { + retArr = append(retArr, "") + continue + } + s, ok := a.(string) + if !ok { + return nil, err + } + retArr = append(retArr, s) + } + return retArr, nil +} + +// MustArray guarantees the return of a `[]interface{}` (with optional default) +// +// useful when you want to interate over array values in a succinct manner: +// for i, v := range js.Get("results").MustArray() { +// fmt.Println(i, v) +// } +func (j *Json) MustArray(args ...[]interface{}) []interface{} { + var def []interface{} + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustArray() received too many arguments %d", len(args)) + } + + a, err := j.Array() + if err == nil { + return a + } + + return def +} + +// MustMap guarantees the return of a `map[string]interface{}` (with optional default) +// +// useful when you want to interate over map values in a succinct manner: +// for k, v := range js.Get("dictionary").MustMap() { +// fmt.Println(k, v) +// } +func (j *Json) MustMap(args ...map[string]interface{}) map[string]interface{} { + var def map[string]interface{} + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustMap() received too many arguments %d", len(args)) + } + + a, err := j.Map() + if err == nil { + return a + } + + return def +} + +// MustString guarantees the return of a `string` (with optional default) +// +// useful when you explicitly want a `string` in a single value return context: +// myFunc(js.Get("param1").MustString(), js.Get("optional_param").MustString("my_default")) +func (j *Json) MustString(args ...string) string { + var def string + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustString() received too many arguments %d", len(args)) + } + + s, err := j.String() + if err == nil { + return s + } + + return def +} + +// MustStringArray guarantees the return of a `[]string` (with optional default) +// +// useful when you want to interate over array values in a succinct manner: +// for i, s := range js.Get("results").MustStringArray() { +// fmt.Println(i, s) +// } +func (j *Json) MustStringArray(args ...[]string) []string { + var def []string + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustStringArray() received too many arguments %d", len(args)) + } + + a, err := j.StringArray() + if err == nil { + return a + } + + return def +} + +// MustInt guarantees the return of an `int` (with optional default) +// +// useful when you explicitly want an `int` in a single value return context: +// myFunc(js.Get("param1").MustInt(), js.Get("optional_param").MustInt(5150)) +func (j *Json) MustInt(args ...int) int { + var def int + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustInt() received too many arguments %d", len(args)) + } + + i, err := j.Int() + if err == nil { + return i + } + + return def +} + +// MustFloat64 guarantees the return of a `float64` (with optional default) +// +// useful when you explicitly want a `float64` in a single value return context: +// myFunc(js.Get("param1").MustFloat64(), js.Get("optional_param").MustFloat64(5.150)) +func (j *Json) MustFloat64(args ...float64) float64 { + var def float64 + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustFloat64() received too many arguments %d", len(args)) + } + + f, err := j.Float64() + if err == nil { + return f + } + + return def +} + +// MustBool guarantees the return of a `bool` (with optional default) +// +// useful when you explicitly want a `bool` in a single value return context: +// myFunc(js.Get("param1").MustBool(), js.Get("optional_param").MustBool(true)) +func (j *Json) MustBool(args ...bool) bool { + var def bool + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustBool() received too many arguments %d", len(args)) + } + + b, err := j.Bool() + if err == nil { + return b + } + + return def +} + +// MustInt64 guarantees the return of an `int64` (with optional default) +// +// useful when you explicitly want an `int64` in a single value return context: +// myFunc(js.Get("param1").MustInt64(), js.Get("optional_param").MustInt64(5150)) +func (j *Json) MustInt64(args ...int64) int64 { + var def int64 + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustInt64() received too many arguments %d", len(args)) + } + + i, err := j.Int64() + if err == nil { + return i + } + + return def +} + +// MustUInt64 guarantees the return of an `uint64` (with optional default) +// +// useful when you explicitly want an `uint64` in a single value return context: +// myFunc(js.Get("param1").MustUint64(), js.Get("optional_param").MustUint64(5150)) +func (j *Json) MustUint64(args ...uint64) uint64 { + var def uint64 + + switch len(args) { + case 0: + case 1: + def = args[0] + default: + log.Panicf("MustUint64() received too many arguments %d", len(args)) + } + + i, err := j.Uint64() + if err == nil { + return i + } + + return def +} diff --git a/pkg/components/simplejson/simplejson_go11.go b/pkg/components/simplejson/simplejson_go11.go new file mode 100644 index 00000000000..3a88b29e449 --- /dev/null +++ b/pkg/components/simplejson/simplejson_go11.go @@ -0,0 +1,91 @@ +// +build go1.1 + +package simplejson + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "reflect" + "strconv" +) + +// Implements the json.Unmarshaler interface. +func (j *Json) UnmarshalJSON(p []byte) error { + fmt.Printf("UnmarshalJSON") + dec := json.NewDecoder(bytes.NewBuffer(p)) + dec.UseNumber() + return dec.Decode(&j.data) +} + +// NewFromReader returns a *Json by decoding from an io.Reader +func NewFromReader(r io.Reader) (*Json, error) { + j := new(Json) + dec := json.NewDecoder(r) + dec.UseNumber() + err := dec.Decode(&j.data) + return j, err +} + +// Float64 coerces into a float64 +func (j *Json) Float64() (float64, error) { + switch j.data.(type) { + case json.Number: + return j.data.(json.Number).Float64() + case float32, float64: + return reflect.ValueOf(j.data).Float(), nil + case int, int8, int16, int32, int64: + return float64(reflect.ValueOf(j.data).Int()), nil + case uint, uint8, uint16, uint32, uint64: + return float64(reflect.ValueOf(j.data).Uint()), nil + } + return 0, errors.New("invalid value type") +} + +// Int coerces into an int +func (j *Json) Int() (int, error) { + switch j.data.(type) { + case json.Number: + i, err := j.data.(json.Number).Int64() + return int(i), err + case float32, float64: + return int(reflect.ValueOf(j.data).Float()), nil + case int, int8, int16, int32, int64: + return int(reflect.ValueOf(j.data).Int()), nil + case uint, uint8, uint16, uint32, uint64: + return int(reflect.ValueOf(j.data).Uint()), nil + } + return 0, errors.New("invalid value type") +} + +// Int64 coerces into an int64 +func (j *Json) Int64() (int64, error) { + switch j.data.(type) { + case json.Number: + return j.data.(json.Number).Int64() + case float32, float64: + return int64(reflect.ValueOf(j.data).Float()), nil + case int, int8, int16, int32, int64: + return reflect.ValueOf(j.data).Int(), nil + case uint, uint8, uint16, uint32, uint64: + return int64(reflect.ValueOf(j.data).Uint()), nil + } + return 0, errors.New("invalid value type") +} + +// Uint64 coerces into an uint64 +func (j *Json) Uint64() (uint64, error) { + switch j.data.(type) { + case json.Number: + return strconv.ParseUint(j.data.(json.Number).String(), 10, 64) + case float32, float64: + return uint64(reflect.ValueOf(j.data).Float()), nil + case int, int8, int16, int32, int64: + return uint64(reflect.ValueOf(j.data).Int()), nil + case uint, uint8, uint16, uint32, uint64: + return reflect.ValueOf(j.data).Uint(), nil + } + return 0, errors.New("invalid value type") +} diff --git a/pkg/components/simplejson/simplejson_test.go b/pkg/components/simplejson/simplejson_test.go new file mode 100644 index 00000000000..b46ffff1873 --- /dev/null +++ b/pkg/components/simplejson/simplejson_test.go @@ -0,0 +1,248 @@ +package simplejson + +import ( + "encoding/json" + "testing" + + "github.com/bmizerany/assert" +) + +func TestSimplejson(t *testing.T) { + var ok bool + var err error + + js, err := NewJson([]byte(`{ + "test": { + "string_array": ["asdf", "ghjk", "zxcv"], + "string_array_null": ["abc", null, "efg"], + "array": [1, "2", 3], + "arraywithsubs": [{"subkeyone": 1}, + {"subkeytwo": 2, "subkeythree": 3}], + "int": 10, + "float": 5.150, + "string": "simplejson", + "bool": true, + "sub_obj": {"a": 1} + } + }`)) + + assert.NotEqual(t, nil, js) + assert.Equal(t, nil, err) + + _, ok = js.CheckGet("test") + assert.Equal(t, true, ok) + + _, ok = js.CheckGet("missing_key") + assert.Equal(t, false, ok) + + aws := js.Get("test").Get("arraywithsubs") + assert.NotEqual(t, nil, aws) + var awsval int + awsval, _ = aws.GetIndex(0).Get("subkeyone").Int() + assert.Equal(t, 1, awsval) + awsval, _ = aws.GetIndex(1).Get("subkeytwo").Int() + assert.Equal(t, 2, awsval) + awsval, _ = aws.GetIndex(1).Get("subkeythree").Int() + assert.Equal(t, 3, awsval) + + i, _ := js.Get("test").Get("int").Int() + assert.Equal(t, 10, i) + + f, _ := js.Get("test").Get("float").Float64() + assert.Equal(t, 5.150, f) + + s, _ := js.Get("test").Get("string").String() + assert.Equal(t, "simplejson", s) + + b, _ := js.Get("test").Get("bool").Bool() + assert.Equal(t, true, b) + + mi := js.Get("test").Get("int").MustInt() + assert.Equal(t, 10, mi) + + mi2 := js.Get("test").Get("missing_int").MustInt(5150) + assert.Equal(t, 5150, mi2) + + ms := js.Get("test").Get("string").MustString() + assert.Equal(t, "simplejson", ms) + + ms2 := js.Get("test").Get("missing_string").MustString("fyea") + assert.Equal(t, "fyea", ms2) + + ma2 := js.Get("test").Get("missing_array").MustArray([]interface{}{"1", 2, "3"}) + assert.Equal(t, ma2, []interface{}{"1", 2, "3"}) + + msa := js.Get("test").Get("string_array").MustStringArray() + assert.Equal(t, msa[0], "asdf") + assert.Equal(t, msa[1], "ghjk") + assert.Equal(t, msa[2], "zxcv") + + msa2 := js.Get("test").Get("string_array").MustStringArray([]string{"1", "2", "3"}) + assert.Equal(t, msa2[0], "asdf") + assert.Equal(t, msa2[1], "ghjk") + assert.Equal(t, msa2[2], "zxcv") + + msa3 := js.Get("test").Get("missing_array").MustStringArray([]string{"1", "2", "3"}) + assert.Equal(t, msa3, []string{"1", "2", "3"}) + + mm2 := js.Get("test").Get("missing_map").MustMap(map[string]interface{}{"found": false}) + assert.Equal(t, mm2, map[string]interface{}{"found": false}) + + strs, err := js.Get("test").Get("string_array").StringArray() + assert.Equal(t, err, nil) + assert.Equal(t, strs[0], "asdf") + assert.Equal(t, strs[1], "ghjk") + assert.Equal(t, strs[2], "zxcv") + + strs2, err := js.Get("test").Get("string_array_null").StringArray() + assert.Equal(t, err, nil) + assert.Equal(t, strs2[0], "abc") + assert.Equal(t, strs2[1], "") + assert.Equal(t, strs2[2], "efg") + + gp, _ := js.GetPath("test", "string").String() + assert.Equal(t, "simplejson", gp) + + gp2, _ := js.GetPath("test", "int").Int() + assert.Equal(t, 10, gp2) + + assert.Equal(t, js.Get("test").Get("bool").MustBool(), true) + + js.Set("float2", 300.0) + assert.Equal(t, js.Get("float2").MustFloat64(), 300.0) + + js.Set("test2", "setTest") + assert.Equal(t, "setTest", js.Get("test2").MustString()) + + js.Del("test2") + assert.NotEqual(t, "setTest", js.Get("test2").MustString()) + + js.Get("test").Get("sub_obj").Set("a", 2) + assert.Equal(t, 2, js.Get("test").Get("sub_obj").Get("a").MustInt()) + + js.GetPath("test", "sub_obj").Set("a", 3) + assert.Equal(t, 3, js.GetPath("test", "sub_obj", "a").MustInt()) +} + +func TestStdlibInterfaces(t *testing.T) { + val := new(struct { + Name string `json:"name"` + Params *Json `json:"params"` + }) + val2 := new(struct { + Name string `json:"name"` + Params *Json `json:"params"` + }) + + raw := `{"name":"myobject","params":{"string":"simplejson"}}` + + assert.Equal(t, nil, json.Unmarshal([]byte(raw), val)) + + assert.Equal(t, "myobject", val.Name) + assert.NotEqual(t, nil, val.Params.data) + s, _ := val.Params.Get("string").String() + assert.Equal(t, "simplejson", s) + + p, err := json.Marshal(val) + assert.Equal(t, nil, err) + assert.Equal(t, nil, json.Unmarshal(p, val2)) + assert.Equal(t, val, val2) // stable +} + +func TestSet(t *testing.T) { + js, err := NewJson([]byte(`{}`)) + assert.Equal(t, nil, err) + + js.Set("baz", "bing") + + s, err := js.GetPath("baz").String() + assert.Equal(t, nil, err) + assert.Equal(t, "bing", s) +} + +func TestReplace(t *testing.T) { + js, err := NewJson([]byte(`{}`)) + assert.Equal(t, nil, err) + + err = js.UnmarshalJSON([]byte(`{"baz":"bing"}`)) + assert.Equal(t, nil, err) + + s, err := js.GetPath("baz").String() + assert.Equal(t, nil, err) + assert.Equal(t, "bing", s) +} + +func TestSetPath(t *testing.T) { + js, err := NewJson([]byte(`{}`)) + assert.Equal(t, nil, err) + + js.SetPath([]string{"foo", "bar"}, "baz") + + s, err := js.GetPath("foo", "bar").String() + assert.Equal(t, nil, err) + assert.Equal(t, "baz", s) +} + +func TestSetPathNoPath(t *testing.T) { + js, err := NewJson([]byte(`{"some":"data","some_number":1.0,"some_bool":false}`)) + assert.Equal(t, nil, err) + + f := js.GetPath("some_number").MustFloat64(99.0) + assert.Equal(t, f, 1.0) + + js.SetPath([]string{}, map[string]interface{}{"foo": "bar"}) + + s, err := js.GetPath("foo").String() + assert.Equal(t, nil, err) + assert.Equal(t, "bar", s) + + f = js.GetPath("some_number").MustFloat64(99.0) + assert.Equal(t, f, 99.0) +} + +func TestPathWillAugmentExisting(t *testing.T) { + js, err := NewJson([]byte(`{"this":{"a":"aa","b":"bb","c":"cc"}}`)) + assert.Equal(t, nil, err) + + js.SetPath([]string{"this", "d"}, "dd") + + cases := []struct { + path []string + outcome string + }{ + { + path: []string{"this", "a"}, + outcome: "aa", + }, + { + path: []string{"this", "b"}, + outcome: "bb", + }, + { + path: []string{"this", "c"}, + outcome: "cc", + }, + { + path: []string{"this", "d"}, + outcome: "dd", + }, + } + + for _, tc := range cases { + s, err := js.GetPath(tc.path...).String() + assert.Equal(t, nil, err) + assert.Equal(t, tc.outcome, s) + } +} + +func TestPathWillOverwriteExisting(t *testing.T) { + // notice how "a" is 0.1 - but then we'll try to set at path a, foo + js, err := NewJson([]byte(`{"this":{"a":0.1,"b":"bb","c":"cc"}}`)) + assert.Equal(t, nil, err) + + js.SetPath([]string{"this", "a", "foo"}, "bar") + + s, err := js.GetPath("this", "a", "foo").String() + assert.Equal(t, nil, err) + assert.Equal(t, "bar", s) +} diff --git a/pkg/models/datasource.go b/pkg/models/datasource.go index 88abd03c319..2e9d98e9700 100644 --- a/pkg/models/datasource.go +++ b/pkg/models/datasource.go @@ -3,6 +3,8 @@ package models import ( "errors" "time" + + "github.com/grafana/grafana/pkg/components/simplejson" ) const ( @@ -42,7 +44,7 @@ type DataSource struct { BasicAuthPassword string WithCredentials bool IsDefault bool - JsonData map[string]interface{} + JsonData *simplejson.Json Created time.Time Updated time.Time @@ -74,19 +76,19 @@ func IsKnownDataSourcePlugin(dsType string) bool { // Also acts as api DTO type AddDataSourceCommand struct { - Name string `json:"name" binding:"Required"` - Type string `json:"type" binding:"Required"` - Access DsAccess `json:"access" binding:"Required"` - Url string `json:"url"` - Password string `json:"password"` - Database string `json:"database"` - User string `json:"user"` - BasicAuth bool `json:"basicAuth"` - BasicAuthUser string `json:"basicAuthUser"` - BasicAuthPassword string `json:"basicAuthPassword"` - WithCredentials bool `json:"withCredentials"` - IsDefault bool `json:"isDefault"` - JsonData map[string]interface{} `json:"jsonData"` + Name string `json:"name" binding:"Required"` + Type string `json:"type" binding:"Required"` + Access DsAccess `json:"access" binding:"Required"` + Url string `json:"url"` + Password string `json:"password"` + Database string `json:"database"` + User string `json:"user"` + BasicAuth bool `json:"basicAuth"` + BasicAuthUser string `json:"basicAuthUser"` + BasicAuthPassword string `json:"basicAuthPassword"` + WithCredentials bool `json:"withCredentials"` + IsDefault bool `json:"isDefault"` + JsonData *simplejson.Json `json:"jsonData"` OrgId int64 `json:"-"` @@ -95,19 +97,19 @@ type AddDataSourceCommand struct { // Also acts as api DTO type UpdateDataSourceCommand struct { - Name string `json:"name" binding:"Required"` - Type string `json:"type" binding:"Required"` - Access DsAccess `json:"access" binding:"Required"` - Url string `json:"url"` - Password string `json:"password"` - User string `json:"user"` - Database string `json:"database"` - BasicAuth bool `json:"basicAuth"` - BasicAuthUser string `json:"basicAuthUser"` - BasicAuthPassword string `json:"basicAuthPassword"` - WithCredentials bool `json:"withCredentials"` - IsDefault bool `json:"isDefault"` - JsonData map[string]interface{} `json:"jsonData"` + Name string `json:"name" binding:"Required"` + Type string `json:"type" binding:"Required"` + Access DsAccess `json:"access" binding:"Required"` + Url string `json:"url"` + Password string `json:"password"` + User string `json:"user"` + Database string `json:"database"` + BasicAuth bool `json:"basicAuth"` + BasicAuthUser string `json:"basicAuthUser"` + BasicAuthPassword string `json:"basicAuthPassword"` + WithCredentials bool `json:"withCredentials"` + IsDefault bool `json:"isDefault"` + JsonData *simplejson.Json `json:"jsonData"` OrgId int64 `json:"-"` Id int64 `json:"-"` diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index a9ee7a6b46c..15e055faffd 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -1,6 +1,10 @@ package plugins import ( + "fmt" + "reflect" + "regexp" + "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/dynmap" "github.com/grafana/grafana/pkg/log" @@ -24,6 +28,14 @@ type ImportDashboardInput struct { Value string `json:"value"` } +type DashboardInputMissingError struct { + VariableName string +} + +func (e DashboardInputMissingError) Error() string { + return fmt.Sprintf("Dashbord input variable: %v missing from import command", e.VariableName) +} + func init() { bus.AddHandler("plugins", ImportDashboard) } @@ -42,8 +54,19 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { return err } + template := dynmap.NewFromMap(dashboard.Data) + evaluator := &DashTemplateEvaluator{ + template: template, + inputs: cmd.Inputs, + } + + generatedDash, err := evaluator.Eval() + if err != nil { + return err + } + saveCmd := m.SaveDashboardCommand{ - Dashboard: dashboard.Data, + Dashboard: generatedDash.StringMap(), OrgId: cmd.OrgId, UserId: cmd.UserId, } @@ -70,15 +93,9 @@ type DashTemplateEvaluator struct { inputs []ImportDashboardInput variables map[string]string result *dynmap.Object + varRegex *regexp.Regexp } -// func (this *DashTemplateEvaluator) getObject(path string) map[string]interface{} { -// if obj, exists := this.template[path]; exists { -// return obj.(map[string]interface{}) -// } -// return nil -// } - func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Object) *ImportDashboardInput { inputType, _ := varDef.GetString("type") @@ -94,14 +111,22 @@ func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Obje func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) { this.result = dynmap.NewObject() this.variables = make(map[string]string) + this.varRegex, _ = regexp.Compile("\\$__(\\w+)") // check that we have all inputs we need if requiredInputs, err := this.template.GetObject("__inputs"); err == nil { for varName, value := range requiredInputs.Map() { varDef, _ := value.Object() input := this.findInput(varName, varDef) - this.variables[varName] = input.Value + + if input == nil { + return nil, &DashboardInputMissingError{VariableName: varName} + } + + this.variables["$__"+varName] = input.Value } + } else { + log.Info("Import: dashboard has no __import section") } this.EvalObject(this.template, this.result) @@ -111,19 +136,24 @@ func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) { func (this *DashTemplateEvaluator) EvalObject(source *dynmap.Object, writer *dynmap.Object) { for key, value := range source.Map() { - if key == "__input" { + if key == "__inputs" { continue } goValue := value.Interface() - switch goValue.(type) { + + switch v := goValue.(type) { case string: - writer.SetValue(key, goValue) + interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string { + return this.variables[match] + }) + writer.SetValue(key, interpolated) case map[string]interface{}: childSource, _ := value.Object() childWriter, _ := writer.SetValue(key, map[string]interface{}{}).Object() this.EvalObject(childSource, childWriter) default: + log.Info("type: %v", reflect.TypeOf(goValue)) log.Error(3, "Unknown json type key: %v , type: %v", key, goValue) } } diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go index 90f4ba2847d..472de6b4e26 100644 --- a/pkg/plugins/dashboard_importer_test.go +++ b/pkg/plugins/dashboard_importer_test.go @@ -33,7 +33,9 @@ func TestDashboardImport(t *testing.T) { Path: "dashboards/connections.json", OrgId: 1, UserId: 1, - Inputs: []ImportDashboardInput{}, + Inputs: []ImportDashboardInput{ + {Name: "*", Type: "datasource"}, + }, } err = ImportDashboard(&cmd) @@ -41,6 +43,10 @@ func TestDashboardImport(t *testing.T) { Convey("should install dashboard", func() { So(importedDash, ShouldNotBeNil) + + dashData := dynmap.NewFromMap(importedDash.Data) + So(dashData.String(), ShouldEqual, "") + rows := importedDash.Data["rows"].([]interface{}) row1 := rows[0].(map[string]interface{}) panels := row1["panels"].([]interface{}) @@ -53,7 +59,7 @@ func TestDashboardImport(t *testing.T) { Convey("When evaling dashboard template", t, func() { template, _ := dynmap.NewObjectFromBytes([]byte(`{ - "__input": { + "__inputs": { "graphite": { "type": "datasource" } @@ -76,6 +82,12 @@ func TestDashboardImport(t *testing.T) { Convey("should render template", func() { So(res.MustGetString("test.prop", ""), ShouldEqual, "my-server") }) + + Convey("should not include inputs in output", func() { + _, err := res.GetObject("__inputs") + So(err, ShouldNotBeNil) + }) + }) } diff --git a/public/app/features/plugins/ds_edit_ctrl.ts b/public/app/features/plugins/ds_edit_ctrl.ts index 1e07b3a814a..d2ca7a82dc4 100644 --- a/public/app/features/plugins/ds_edit_ctrl.ts +++ b/public/app/features/plugins/ds_edit_ctrl.ts @@ -24,6 +24,7 @@ export class DataSourceEditCtrl { datasourceMeta: any; tabIndex: number; hasDashboards: boolean; + editForm: any; /** @ngInject */ constructor( @@ -114,7 +115,7 @@ export class DataSourceEditCtrl { } saveChanges(test) { - if (!this.$scope.editForm.$valid) { + if (!this.editForm.$valid) { return; } diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index d519b78ae55..ff2f981e58b 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -25,7 +25,7 @@
-
+
Name @@ -52,12 +52,12 @@ -
-
Testing....
-
Test results
-
-
{{testing.title}}
-
+
+
Testing....
+
Test results
+
+
{{ctrl.testing.title}}
+
diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json index e206d8be57d..3cdfb0049c9 100644 --- a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json +++ b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json @@ -14,7 +14,7 @@ "panels": [ { "type": "graph", - "datasource": "__$graphite" + "datasource": "$__graphite" } ] } From 749da42ffcb740d27d8d465ef3bdd84c35e06fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 11 Mar 2016 23:29:45 +0100 Subject: [PATCH 05/33] updated lib --- Godeps/Godeps.json | 18 +- .../github.com/bmizerany/assert/.gitignore | 7 + .../src/github.com/bmizerany/assert/README.md | 45 +++ .../src/github.com/bmizerany/assert/assert.go | 76 ++++ .../bmizerany/assert/assert_test.go | 15 + .../bmizerany/assert/example/point.go | 5 + .../bmizerany/assert/example/point_test.go | 13 + .../src/github.com/gopherjs/gopherjs/js/js.go | 168 --------- .../src/github.com/kr/pretty/.gitignore | 4 + .../src/github.com/kr/pretty/License | 21 ++ .../src/github.com/kr/pretty/Readme | 9 + .../src/github.com/kr/pretty/diff.go | 158 ++++++++ .../src/github.com/kr/pretty/diff_test.go | 74 ++++ .../src/github.com/kr/pretty/example_test.go | 20 ++ .../src/github.com/kr/pretty/formatter.go | 337 ++++++++++++++++++ .../github.com/kr/pretty/formatter_test.go | 261 ++++++++++++++ .../src/github.com/kr/pretty/pretty.go | 98 +++++ .../src/github.com/kr/pretty/zero.go | 41 +++ .../_workspace/src/github.com/kr/text/License | 19 + .../_workspace/src/github.com/kr/text/Readme | 3 + .../src/github.com/kr/text/colwriter/Readme | 5 + .../github.com/kr/text/colwriter/column.go | 147 ++++++++ .../kr/text/colwriter/column_test.go | 90 +++++ .../_workspace/src/github.com/kr/text/doc.go | 3 + .../src/github.com/kr/text/indent.go | 74 ++++ .../src/github.com/kr/text/indent_test.go | 119 +++++++ .../src/github.com/kr/text/mc/Readme | 9 + .../src/github.com/kr/text/mc/mc.go | 62 ++++ .../_workspace/src/github.com/kr/text/wrap.go | 86 +++++ .../src/github.com/kr/text/wrap_test.go | 62 ++++ 30 files changed, 1877 insertions(+), 172 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/.gitignore create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/README.md create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/assert.go create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/assert_test.go create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/example/point.go create mode 100644 Godeps/_workspace/src/github.com/bmizerany/assert/example/point_test.go delete mode 100644 Godeps/_workspace/src/github.com/gopherjs/gopherjs/js/js.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/.gitignore create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/License create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/Readme create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/diff.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/diff_test.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/example_test.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/formatter.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/formatter_test.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/pretty.go create mode 100644 Godeps/_workspace/src/github.com/kr/pretty/zero.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/License create mode 100644 Godeps/_workspace/src/github.com/kr/text/Readme create mode 100644 Godeps/_workspace/src/github.com/kr/text/colwriter/Readme create mode 100644 Godeps/_workspace/src/github.com/kr/text/colwriter/column.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/colwriter/column_test.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/doc.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/indent.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/indent_test.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/mc/Readme create mode 100644 Godeps/_workspace/src/github.com/kr/text/mc/mc.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/wrap.go create mode 100644 Godeps/_workspace/src/github.com/kr/text/wrap_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index b75fdfb574a..bc1cb68bb5b 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -64,6 +64,11 @@ "Comment": "v1.0.0", "Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f" }, + { + "ImportPath": "github.com/bmizerany/assert", + "Comment": "release.r60-6-ge17e998", + "Rev": "e17e99893cb6509f428e1728281c2ad60a6b31e3" + }, { "ImportPath": "github.com/bradfitz/gomemcache/memcache", "Comment": "release.r60-40-g72a6864", @@ -123,10 +128,6 @@ "Comment": "v0.4.4-44-gf561133", "Rev": "f56113384f2c63dfe4cd8e768e349f1c35122b58" }, - { - "ImportPath": "github.com/gopherjs/gopherjs/js", - "Rev": "14d893dca2e4adb93a5ccc9494040acc0821cd8d" - }, { "ImportPath": "github.com/gosimple/slug", "Rev": "8d258463b4459f161f51d6a357edacd3eef9d663" @@ -160,6 +161,15 @@ "ImportPath": "github.com/klauspost/crc32", "Rev": "6834731faf32e62a2dd809d99fb24d1e4ae5a92d" }, + { + "ImportPath": "github.com/kr/pretty", + "Comment": "go.weekly.2011-12-22-27-ge6ac2fc", + "Rev": "e6ac2fc51e89a3249e82157fa0bb7a18ef9dd5bb" + }, + { + "ImportPath": "github.com/kr/text", + "Rev": "bb797dc4fb8320488f47bf11de07a733d7233e1f" + }, { "ImportPath": "github.com/lib/pq", "Comment": "go1.0-cutoff-13-g19eeca3", diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/.gitignore b/Godeps/_workspace/src/github.com/bmizerany/assert/.gitignore new file mode 100644 index 00000000000..b6fadf4ebe7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/.gitignore @@ -0,0 +1,7 @@ +_go_.* +_gotest_.* +_obj +_test +_testmain.go +*.out +*.[568] diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/README.md b/Godeps/_workspace/src/github.com/bmizerany/assert/README.md new file mode 100644 index 00000000000..8b6b6fc4fc6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/README.md @@ -0,0 +1,45 @@ +# Assert (c) Blake Mizerany and Keith Rarick -- MIT LICENCE + +## Assertions for Go tests + +## Install + + $ go get github.com/bmizerany/assert + +## Use + +**point.go** + + package point + + type Point struct { + x, y int + } + +**point_test.go** + + + package point + + import ( + "testing" + "github.com/bmizerany/assert" + ) + + func TestAsserts(t *testing.T) { + p1 := Point{1, 1} + p2 := Point{2, 1} + + assert.Equal(t, p1, p2) + } + +**output** + $ go test + --- FAIL: TestAsserts (0.00 seconds) + assert.go:15: /Users/flavio.barbosa/dev/stewie/src/point_test.go:12 + assert.go:24: ! X: 1 != 2 + FAIL + +## Docs + + http://github.com/bmizerany/assert diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/assert.go b/Godeps/_workspace/src/github.com/bmizerany/assert/assert.go new file mode 100644 index 00000000000..7409f985e80 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/assert.go @@ -0,0 +1,76 @@ +package assert +// Testing helpers for doozer. + +import ( + "github.com/kr/pretty" + "reflect" + "testing" + "runtime" + "fmt" +) + +func assert(t *testing.T, result bool, f func(), cd int) { + if !result { + _, file, line, _ := runtime.Caller(cd + 1) + t.Errorf("%s:%d", file, line) + f() + t.FailNow() + } +} + +func equal(t *testing.T, exp, got interface{}, cd int, args ...interface{}) { + fn := func() { + for _, desc := range pretty.Diff(exp, got) { + t.Error("!", desc) + } + if len(args) > 0 { + t.Error("!", " -", fmt.Sprint(args...)) + } + } + result := reflect.DeepEqual(exp, got) + assert(t, result, fn, cd+1) +} + +func tt(t *testing.T, result bool, cd int, args ...interface{}) { + fn := func() { + t.Errorf("! Failure") + if len(args) > 0 { + t.Error("!", " -", fmt.Sprint(args...)) + } + } + assert(t, result, fn, cd+1) +} + +func T(t *testing.T, result bool, args ...interface{}) { + tt(t, result, 1, args...) +} + +func Tf(t *testing.T, result bool, format string, args ...interface{}) { + tt(t, result, 1, fmt.Sprintf(format, args...)) +} + +func Equal(t *testing.T, exp, got interface{}, args ...interface{}) { + equal(t, exp, got, 1, args...) +} + +func Equalf(t *testing.T, exp, got interface{}, format string, args ...interface{}) { + equal(t, exp, got, 1, fmt.Sprintf(format, args...)) +} + +func NotEqual(t *testing.T, exp, got interface{}, args ...interface{}) { + fn := func() { + t.Errorf("! Unexpected: <%#v>", exp) + if len(args) > 0 { + t.Error("!", " -", fmt.Sprint(args...)) + } + } + result := !reflect.DeepEqual(exp, got) + assert(t, result, fn, 1) +} + +func Panic(t *testing.T, err interface{}, fn func()) { + defer func() { + equal(t, err, recover(), 3) + }() + fn() +} diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/assert_test.go b/Godeps/_workspace/src/github.com/bmizerany/assert/assert_test.go new file mode 100644 index 00000000000..162a590c62f --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/assert_test.go @@ -0,0 +1,15 @@ +package assert + +import ( + "testing" +) + +func TestLineNumbers(t *testing.T) { + Equal(t, "foo", "foo", "msg!") + //Equal(t, "foo", "bar", "this should blow up") +} + +func TestNotEqual(t *testing.T) { + NotEqual(t, "foo", "bar", "msg!") + //NotEqual(t, "foo", "foo", "this should blow up") +} diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/example/point.go b/Godeps/_workspace/src/github.com/bmizerany/assert/example/point.go new file mode 100644 index 00000000000..15789fe10f4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/example/point.go @@ -0,0 +1,5 @@ +package point + +type Point struct { + X, Y int +} diff --git a/Godeps/_workspace/src/github.com/bmizerany/assert/example/point_test.go b/Godeps/_workspace/src/github.com/bmizerany/assert/example/point_test.go new file mode 100644 index 00000000000..34e791a43c9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bmizerany/assert/example/point_test.go @@ -0,0 +1,13 @@ +package point + +import ( + "testing" + "assert" +) + +func TestAsserts(t *testing.T) { + p1 := Point{1, 1} + p2 := Point{2, 1} + + assert.Equal(t, p1, p2) +} diff --git a/Godeps/_workspace/src/github.com/gopherjs/gopherjs/js/js.go b/Godeps/_workspace/src/github.com/gopherjs/gopherjs/js/js.go deleted file mode 100644 index 5367d3d0fa7..00000000000 --- a/Godeps/_workspace/src/github.com/gopherjs/gopherjs/js/js.go +++ /dev/null @@ -1,168 +0,0 @@ -// Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax. -// -// Use MakeWrapper to expose methods to JavaScript. When passing values directly, the following type conversions are performed: -// -// | Go type | JavaScript type | Conversions back to interface{} | -// | --------------------- | --------------------- | ------------------------------- | -// | bool | Boolean | bool | -// | integers and floats | Number | float64 | -// | string | String | string | -// | []int8 | Int8Array | []int8 | -// | []int16 | Int16Array | []int16 | -// | []int32, []int | Int32Array | []int | -// | []uint8 | Uint8Array | []uint8 | -// | []uint16 | Uint16Array | []uint16 | -// | []uint32, []uint | Uint32Array | []uint | -// | []float32 | Float32Array | []float32 | -// | []float64 | Float64Array | []float64 | -// | all other slices | Array | []interface{} | -// | arrays | see slice type | see slice type | -// | functions | Function | func(...interface{}) *js.Object | -// | time.Time | Date | time.Time | -// | - | instanceof Node | *js.Object | -// | maps, structs | instanceof Object | map[string]interface{} | -// -// Additionally, for a struct containing a *js.Object field, only the content of the field will be passed to JavaScript and vice versa. -package js - -// Object is a container for a native JavaScript object. Calls to its methods are treated specially by GopherJS and translated directly to their JavaScript syntax. A nil pointer to Object is equal to JavaScript's "null". Object can not be used as a map key. -type Object struct{ object *Object } - -// Get returns the object's property with the given key. -func (o *Object) Get(key string) *Object { return o.object.Get(key) } - -// Set assigns the value to the object's property with the given key. -func (o *Object) Set(key string, value interface{}) { o.object.Set(key, value) } - -// Delete removes the object's property with the given key. -func (o *Object) Delete(key string) { o.object.Delete(key) } - -// Length returns the object's "length" property, converted to int. -func (o *Object) Length() int { return o.object.Length() } - -// Index returns the i'th element of an array. -func (o *Object) Index(i int) *Object { return o.object.Index(i) } - -// SetIndex sets the i'th element of an array. -func (o *Object) SetIndex(i int, value interface{}) { o.object.SetIndex(i, value) } - -// Call calls the object's method with the given name. -func (o *Object) Call(name string, args ...interface{}) *Object { return o.object.Call(name, args...) } - -// Invoke calls the object itself. This will fail if it is not a function. -func (o *Object) Invoke(args ...interface{}) *Object { return o.object.Invoke(args...) } - -// New creates a new instance of this type object. This will fail if it not a function (constructor). -func (o *Object) New(args ...interface{}) *Object { return o.object.New(args...) } - -// Bool returns the object converted to bool according to JavaScript type conversions. -func (o *Object) Bool() bool { return o.object.Bool() } - -// String returns the object converted to string according to JavaScript type conversions. -func (o *Object) String() string { return o.object.String() } - -// Int returns the object converted to int according to JavaScript type conversions (parseInt). -func (o *Object) Int() int { return o.object.Int() } - -// Int64 returns the object converted to int64 according to JavaScript type conversions (parseInt). -func (o *Object) Int64() int64 { return o.object.Int64() } - -// Uint64 returns the object converted to uint64 according to JavaScript type conversions (parseInt). -func (o *Object) Uint64() uint64 { return o.object.Uint64() } - -// Float returns the object converted to float64 according to JavaScript type conversions (parseFloat). -func (o *Object) Float() float64 { return o.object.Float() } - -// Interface returns the object converted to interface{}. See GopherJS' README for details. -func (o *Object) Interface() interface{} { return o.object.Interface() } - -// Unsafe returns the object as an uintptr, which can be converted via unsafe.Pointer. Not intended for public use. -func (o *Object) Unsafe() uintptr { return o.object.Unsafe() } - -// Error encapsulates JavaScript errors. Those are turned into a Go panic and may be recovered, giving an *Error that holds the JavaScript error object. -type Error struct { - *Object -} - -// Error returns the message of the encapsulated JavaScript error object. -func (err *Error) Error() string { - return "JavaScript error: " + err.Get("message").String() -} - -// Stack returns the stack property of the encapsulated JavaScript error object. -func (err *Error) Stack() string { - return err.Get("stack").String() -} - -// Global gives JavaScript's global object ("window" for browsers and "GLOBAL" for Node.js). -var Global *Object - -// Module gives the value of the "module" variable set by Node.js. Hint: Set a module export with 'js.Module.Get("exports").Set("exportName", ...)'. -var Module *Object - -// Undefined gives the JavaScript value "undefined". -var Undefined *Object - -// Debugger gets compiled to JavaScript's "debugger;" statement. -func Debugger() {} - -// InternalObject returns the internal JavaScript object that represents i. Not intended for public use. -func InternalObject(i interface{}) *Object { - return nil -} - -// MakeFunc wraps a function and gives access to the values of JavaScript's "this" and "arguments" keywords. -func MakeFunc(func(this *Object, arguments []*Object) interface{}) *Object { - return nil -} - -// Keys returns the keys of the given JavaScript object. -func Keys(o *Object) []string { - if o == nil || o == Undefined { - return nil - } - a := Global.Get("Object").Call("keys", o) - s := make([]string, a.Length()) - for i := 0; i < a.Length(); i++ { - s[i] = a.Index(i).String() - } - return s -} - -// MakeWrapper creates a JavaScript object which has wrappers for the exported methods of i. Use explicit getter and setter methods to expose struct fields to JavaScript. -func MakeWrapper(i interface{}) *Object { - v := InternalObject(i) - o := Global.Get("Object").New() - o.Set("__internal_object__", v) - methods := v.Get("constructor").Get("methods") - for i := 0; i < methods.Length(); i++ { - m := methods.Index(i) - if m.Get("pkg").String() != "" { // not exported - continue - } - o.Set(m.Get("name").String(), func(args ...*Object) *Object { - return Global.Call("$externalizeFunction", v.Get(m.Get("prop").String()), m.Get("typ"), true).Call("apply", v, args) - }) - } - return o -} - -// NewArrayBuffer creates a JavaScript ArrayBuffer from a byte slice. -func NewArrayBuffer(b []byte) *Object { - slice := InternalObject(b) - offset := slice.Get("$offset").Int() - length := slice.Get("$length").Int() - return slice.Get("$array").Get("buffer").Call("slice", offset, offset+length) -} - -// M is a simple map type. It is intended as a shorthand for JavaScript objects (before conversion). -type M map[string]interface{} - -// S is a simple slice type. It is intended as a shorthand for JavaScript arrays (before conversion). -type S []interface{} - -func init() { - // avoid dead code elimination - e := Error{} - _ = e -} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/.gitignore b/Godeps/_workspace/src/github.com/kr/pretty/.gitignore new file mode 100644 index 00000000000..1f0a99f2f2b --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/.gitignore @@ -0,0 +1,4 @@ +[568].out +_go* +_test* +_obj diff --git a/Godeps/_workspace/src/github.com/kr/pretty/License b/Godeps/_workspace/src/github.com/kr/pretty/License new file mode 100644 index 00000000000..05c783ccf68 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/License @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright 2012 Keith Rarick + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/kr/pretty/Readme b/Godeps/_workspace/src/github.com/kr/pretty/Readme new file mode 100644 index 00000000000..c589fc622b3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/Readme @@ -0,0 +1,9 @@ +package pretty + + import "github.com/kr/pretty" + + Package pretty provides pretty-printing for Go values. + +Documentation + + http://godoc.org/github.com/kr/pretty diff --git a/Godeps/_workspace/src/github.com/kr/pretty/diff.go b/Godeps/_workspace/src/github.com/kr/pretty/diff.go new file mode 100644 index 00000000000..8fe8e2405a0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/diff.go @@ -0,0 +1,158 @@ +package pretty + +import ( + "fmt" + "io" + "reflect" +) + +type sbuf []string + +func (s *sbuf) Write(b []byte) (int, error) { + *s = append(*s, string(b)) + return len(b), nil +} + +// Diff returns a slice where each element describes +// a difference between a and b. +func Diff(a, b interface{}) (desc []string) { + Fdiff((*sbuf)(&desc), a, b) + return desc +} + +// Fdiff writes to w a description of the differences between a and b. +func Fdiff(w io.Writer, a, b interface{}) { + diffWriter{w: w}.diff(reflect.ValueOf(a), reflect.ValueOf(b)) +} + +type diffWriter struct { + w io.Writer + l string // label +} + +func (w diffWriter) printf(f string, a ...interface{}) { + var l string + if w.l != "" { + l = w.l + ": " + } + fmt.Fprintf(w.w, l+f, a...) +} + +func (w diffWriter) diff(av, bv reflect.Value) { + if !av.IsValid() && bv.IsValid() { + w.printf("nil != %#v", bv.Interface()) + return + } + if av.IsValid() && !bv.IsValid() { + w.printf("%#v != nil", av.Interface()) + return + } + if !av.IsValid() && !bv.IsValid() { + return + } + + at := av.Type() + bt := bv.Type() + if at != bt { + w.printf("%v != %v", at, bt) + return + } + + // numeric types, including bool + if at.Kind() < reflect.Array { + a, b := av.Interface(), bv.Interface() + if a != b { + w.printf("%#v != %#v", a, b) + } + return + } + + switch at.Kind() { + case reflect.String: + a, b := av.Interface(), bv.Interface() + if a != b { + w.printf("%q != %q", a, b) + } + case reflect.Ptr: + switch { + case av.IsNil() && !bv.IsNil(): + w.printf("nil != %v", bv.Interface()) + case !av.IsNil() && bv.IsNil(): + w.printf("%v != nil", av.Interface()) + case !av.IsNil() && !bv.IsNil(): + w.diff(av.Elem(), bv.Elem()) + } + case reflect.Struct: + for i := 0; i < av.NumField(); i++ { + w.relabel(at.Field(i).Name).diff(av.Field(i), bv.Field(i)) + } + case reflect.Slice: + lenA := av.Len() + lenB := bv.Len() + if lenA != lenB { + w.printf("%s[%d] != %s[%d]", av.Type(), lenA, bv.Type(), lenB) + break + } + for i := 0; i < lenA; i++ { + w.relabel(fmt.Sprintf("[%d]", i)).diff(av.Index(i), bv.Index(i)) + } + case reflect.Map: + ak, both, bk := keyDiff(av.MapKeys(), bv.MapKeys()) + for _, k := range ak { + w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) + w.printf("%q != (missing)", av.MapIndex(k)) + } + for _, k := range both { + w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) + w.diff(av.MapIndex(k), bv.MapIndex(k)) + } + for _, k := range bk { + w := w.relabel(fmt.Sprintf("[%#v]", k.Interface())) + w.printf("(missing) != %q", bv.MapIndex(k)) + } + case reflect.Interface: + w.diff(reflect.ValueOf(av.Interface()), reflect.ValueOf(bv.Interface())) + default: + if !reflect.DeepEqual(av.Interface(), bv.Interface()) { + w.printf("%# v != %# v", Formatter(av.Interface()), Formatter(bv.Interface())) + } + } +} + +func (d diffWriter) relabel(name string) (d1 diffWriter) { + d1 = d + if d.l != "" && name[0] != '[' { + d1.l += "." + } + d1.l += name + return d1 +} + +func keyDiff(a, b []reflect.Value) (ak, both, bk []reflect.Value) { + for _, av := range a { + inBoth := false + for _, bv := range b { + if reflect.DeepEqual(av.Interface(), bv.Interface()) { + inBoth = true + both = append(both, av) + break + } + } + if !inBoth { + ak = append(ak, av) + } + } + for _, bv := range b { + inBoth := false + for _, av := range a { + if reflect.DeepEqual(av.Interface(), bv.Interface()) { + inBoth = true + break + } + } + if !inBoth { + bk = append(bk, bv) + } + } + return +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/diff_test.go b/Godeps/_workspace/src/github.com/kr/pretty/diff_test.go new file mode 100644 index 00000000000..3c388f13ca7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/diff_test.go @@ -0,0 +1,74 @@ +package pretty + +import ( + "testing" +) + +type difftest struct { + a interface{} + b interface{} + exp []string +} + +type S struct { + A int + S *S + I interface{} + C []int +} + +var diffs = []difftest{ + {a: nil, b: nil}, + {a: S{A: 1}, b: S{A: 1}}, + + {0, "", []string{`int != string`}}, + {0, 1, []string{`0 != 1`}}, + {S{}, new(S), []string{`pretty.S != *pretty.S`}}, + {"a", "b", []string{`"a" != "b"`}}, + {S{}, S{A: 1}, []string{`A: 0 != 1`}}, + {new(S), &S{A: 1}, []string{`A: 0 != 1`}}, + {S{S: new(S)}, S{S: &S{A: 1}}, []string{`S.A: 0 != 1`}}, + {S{}, S{I: 0}, []string{`I: nil != 0`}}, + {S{I: 1}, S{I: "x"}, []string{`I: int != string`}}, + {S{}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, + {S{C: []int{}}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, + {S{C: []int{1, 2, 3}}, S{C: []int{1, 2, 4}}, []string{`C[2]: 3 != 4`}}, + {S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &{0 []}`}}, +} + +func TestDiff(t *testing.T) { + for _, tt := range diffs { + got := Diff(tt.a, tt.b) + eq := len(got) == len(tt.exp) + if eq { + for i := range got { + eq = eq && got[i] == tt.exp[i] + } + } + if !eq { + t.Errorf("diffing % #v", tt.a) + t.Errorf("with % #v", tt.b) + diffdiff(t, got, tt.exp) + continue + } + } +} + +func diffdiff(t *testing.T, got, exp []string) { + minus(t, "unexpected:", got, exp) + minus(t, "missing:", exp, got) +} + +func minus(t *testing.T, s string, a, b []string) { + var i, j int + for i = 0; i < len(a); i++ { + for j = 0; j < len(b); j++ { + if a[i] == b[j] { + break + } + } + if j == len(b) { + t.Error(s, a[i]) + } + } +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/example_test.go b/Godeps/_workspace/src/github.com/kr/pretty/example_test.go new file mode 100644 index 00000000000..ecf40f3fcc6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/example_test.go @@ -0,0 +1,20 @@ +package pretty_test + +import ( + "fmt" + "github.com/kr/pretty" +) + +func Example() { + type myType struct { + a, b int + } + var x = []myType{{1, 2}, {3, 4}, {5, 6}} + fmt.Printf("%# v", pretty.Formatter(x)) + // output: + // []pretty_test.myType{ + // {a:1, b:2}, + // {a:3, b:4}, + // {a:5, b:6}, + // } +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/formatter.go b/Godeps/_workspace/src/github.com/kr/pretty/formatter.go new file mode 100644 index 00000000000..8dacda25fa8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/formatter.go @@ -0,0 +1,337 @@ +package pretty + +import ( + "fmt" + "io" + "reflect" + "strconv" + "text/tabwriter" + + "github.com/kr/text" +) + +const ( + limit = 50 +) + +type formatter struct { + x interface{} + force bool + quote bool +} + +// Formatter makes a wrapper, f, that will format x as go source with line +// breaks and tabs. Object f responds to the "%v" formatting verb when both the +// "#" and " " (space) flags are set, for example: +// +// fmt.Sprintf("%# v", Formatter(x)) +// +// If one of these two flags is not set, or any other verb is used, f will +// format x according to the usual rules of package fmt. +// In particular, if x satisfies fmt.Formatter, then x.Format will be called. +func Formatter(x interface{}) (f fmt.Formatter) { + return formatter{x: x, quote: true} +} + +func (fo formatter) String() string { + return fmt.Sprint(fo.x) // unwrap it +} + +func (fo formatter) passThrough(f fmt.State, c rune) { + s := "%" + for i := 0; i < 128; i++ { + if f.Flag(i) { + s += string(i) + } + } + if w, ok := f.Width(); ok { + s += fmt.Sprintf("%d", w) + } + if p, ok := f.Precision(); ok { + s += fmt.Sprintf(".%d", p) + } + s += string(c) + fmt.Fprintf(f, s, fo.x) +} + +func (fo formatter) Format(f fmt.State, c rune) { + if fo.force || c == 'v' && f.Flag('#') && f.Flag(' ') { + w := tabwriter.NewWriter(f, 4, 4, 1, ' ', 0) + p := &printer{tw: w, Writer: w, visited: make(map[visit]int)} + p.printValue(reflect.ValueOf(fo.x), true, fo.quote) + w.Flush() + return + } + fo.passThrough(f, c) +} + +type printer struct { + io.Writer + tw *tabwriter.Writer + visited map[visit]int + depth int +} + +func (p *printer) indent() *printer { + q := *p + q.tw = tabwriter.NewWriter(p.Writer, 4, 4, 1, ' ', 0) + q.Writer = text.NewIndentWriter(q.tw, []byte{'\t'}) + return &q +} + +func (p *printer) printInline(v reflect.Value, x interface{}, showType bool) { + if showType { + io.WriteString(p, v.Type().String()) + fmt.Fprintf(p, "(%#v)", x) + } else { + fmt.Fprintf(p, "%#v", x) + } +} + +// printValue must keep track of already-printed pointer values to avoid +// infinite recursion. +type visit struct { + v uintptr + typ reflect.Type +} + +func (p *printer) printValue(v reflect.Value, showType, quote bool) { + if p.depth > 10 { + io.WriteString(p, "!%v(DEPTH EXCEEDED)") + return + } + + switch v.Kind() { + case reflect.Bool: + p.printInline(v, v.Bool(), showType) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p.printInline(v, v.Int(), showType) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p.printInline(v, v.Uint(), showType) + case reflect.Float32, reflect.Float64: + p.printInline(v, v.Float(), showType) + case reflect.Complex64, reflect.Complex128: + fmt.Fprintf(p, "%#v", v.Complex()) + case reflect.String: + p.fmtString(v.String(), quote) + case reflect.Map: + t := v.Type() + if showType { + io.WriteString(p, t.String()) + } + writeByte(p, '{') + if nonzero(v) { + expand := !canInline(v.Type()) + pp := p + if expand { + writeByte(p, '\n') + pp = p.indent() + } + keys := v.MapKeys() + for i := 0; i < v.Len(); i++ { + showTypeInStruct := true + k := keys[i] + mv := v.MapIndex(k) + pp.printValue(k, false, true) + writeByte(pp, ':') + if expand { + writeByte(pp, '\t') + } + showTypeInStruct = t.Elem().Kind() == reflect.Interface + pp.printValue(mv, showTypeInStruct, true) + if expand { + io.WriteString(pp, ",\n") + } else if i < v.Len()-1 { + io.WriteString(pp, ", ") + } + } + if expand { + pp.tw.Flush() + } + } + writeByte(p, '}') + case reflect.Struct: + t := v.Type() + if v.CanAddr() { + addr := v.UnsafeAddr() + vis := visit{addr, t} + if vd, ok := p.visited[vis]; ok && vd < p.depth { + p.fmtString(t.String()+"{(CYCLIC REFERENCE)}", false) + break // don't print v again + } + p.visited[vis] = p.depth + } + + if showType { + io.WriteString(p, t.String()) + } + writeByte(p, '{') + if nonzero(v) { + expand := !canInline(v.Type()) + pp := p + if expand { + writeByte(p, '\n') + pp = p.indent() + } + for i := 0; i < v.NumField(); i++ { + showTypeInStruct := true + if f := t.Field(i); f.Name != "" { + io.WriteString(pp, f.Name) + writeByte(pp, ':') + if expand { + writeByte(pp, '\t') + } + showTypeInStruct = labelType(f.Type) + } + pp.printValue(getField(v, i), showTypeInStruct, true) + if expand { + io.WriteString(pp, ",\n") + } else if i < v.NumField()-1 { + io.WriteString(pp, ", ") + } + } + if expand { + pp.tw.Flush() + } + } + writeByte(p, '}') + case reflect.Interface: + switch e := v.Elem(); { + case e.Kind() == reflect.Invalid: + io.WriteString(p, "nil") + case e.IsValid(): + pp := *p + pp.depth++ + pp.printValue(e, showType, true) + default: + io.WriteString(p, v.Type().String()) + io.WriteString(p, "(nil)") + } + case reflect.Array, reflect.Slice: + t := v.Type() + if showType { + io.WriteString(p, t.String()) + } + if v.Kind() == reflect.Slice && v.IsNil() && showType { + io.WriteString(p, "(nil)") + break + } + if v.Kind() == reflect.Slice && v.IsNil() { + io.WriteString(p, "nil") + break + } + writeByte(p, '{') + expand := !canInline(v.Type()) + pp := p + if expand { + writeByte(p, '\n') + pp = p.indent() + } + for i := 0; i < v.Len(); i++ { + showTypeInSlice := t.Elem().Kind() == reflect.Interface + pp.printValue(v.Index(i), showTypeInSlice, true) + if expand { + io.WriteString(pp, ",\n") + } else if i < v.Len()-1 { + io.WriteString(pp, ", ") + } + } + if expand { + pp.tw.Flush() + } + writeByte(p, '}') + case reflect.Ptr: + e := v.Elem() + if !e.IsValid() { + writeByte(p, '(') + io.WriteString(p, v.Type().String()) + io.WriteString(p, ")(nil)") + } else { + pp := *p + pp.depth++ + writeByte(pp, '&') + pp.printValue(e, true, true) + } + case reflect.Chan: + x := v.Pointer() + if showType { + writeByte(p, '(') + io.WriteString(p, v.Type().String()) + fmt.Fprintf(p, ")(%#v)", x) + } else { + fmt.Fprintf(p, "%#v", x) + } + case reflect.Func: + io.WriteString(p, v.Type().String()) + io.WriteString(p, " {...}") + case reflect.UnsafePointer: + p.printInline(v, v.Pointer(), showType) + case reflect.Invalid: + io.WriteString(p, "nil") + } +} + +func canInline(t reflect.Type) bool { + switch t.Kind() { + case reflect.Map: + return !canExpand(t.Elem()) + case reflect.Struct: + for i := 0; i < t.NumField(); i++ { + if canExpand(t.Field(i).Type) { + return false + } + } + return true + case reflect.Interface: + return false + case reflect.Array, reflect.Slice: + return !canExpand(t.Elem()) + case reflect.Ptr: + return false + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + return false + } + return true +} + +func canExpand(t reflect.Type) bool { + switch t.Kind() { + case reflect.Map, reflect.Struct, + reflect.Interface, reflect.Array, reflect.Slice, + reflect.Ptr: + return true + } + return false +} + +func labelType(t reflect.Type) bool { + switch t.Kind() { + case reflect.Interface, reflect.Struct: + return true + } + return false +} + +func (p *printer) fmtString(s string, quote bool) { + if quote { + s = strconv.Quote(s) + } + io.WriteString(p, s) +} + +func tryDeepEqual(a, b interface{}) bool { + defer func() { recover() }() + return reflect.DeepEqual(a, b) +} + +func writeByte(w io.Writer, b byte) { + w.Write([]byte{b}) +} + +func getField(v reflect.Value, i int) reflect.Value { + val := v.Field(i) + if val.Kind() == reflect.Interface && !val.IsNil() { + val = val.Elem() + } + return val +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/formatter_test.go b/Godeps/_workspace/src/github.com/kr/pretty/formatter_test.go new file mode 100644 index 00000000000..5f3204e8e87 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/formatter_test.go @@ -0,0 +1,261 @@ +package pretty + +import ( + "fmt" + "io" + "strings" + "testing" + "unsafe" +) + +type test struct { + v interface{} + s string +} + +type LongStructTypeName struct { + longFieldName interface{} + otherLongFieldName interface{} +} + +type SA struct { + t *T + v T +} + +type T struct { + x, y int +} + +type F int + +func (f F) Format(s fmt.State, c rune) { + fmt.Fprintf(s, "F(%d)", int(f)) +} + +var long = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +var gosyntax = []test{ + {nil, `nil`}, + {"", `""`}, + {"a", `"a"`}, + {1, "int(1)"}, + {1.0, "float64(1)"}, + {[]int(nil), "[]int(nil)"}, + {[0]int{}, "[0]int{}"}, + {complex(1, 0), "(1+0i)"}, + //{make(chan int), "(chan int)(0x1234)"}, + {unsafe.Pointer(uintptr(unsafe.Pointer(&long))), fmt.Sprintf("unsafe.Pointer(0x%02x)", uintptr(unsafe.Pointer(&long)))}, + {func(int) {}, "func(int) {...}"}, + {map[int]int{1: 1}, "map[int]int{1:1}"}, + {int32(1), "int32(1)"}, + {io.EOF, `&errors.errorString{s:"EOF"}`}, + {[]string{"a"}, `[]string{"a"}`}, + { + []string{long}, + `[]string{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}`, + }, + {F(5), "pretty.F(5)"}, + { + SA{&T{1, 2}, T{3, 4}}, + `pretty.SA{ + t: &pretty.T{x:1, y:2}, + v: pretty.T{x:3, y:4}, +}`, + }, + { + map[int][]byte{1: {}}, + `map[int][]uint8{ + 1: {}, +}`, + }, + { + map[int]T{1: {}}, + `map[int]pretty.T{ + 1: {}, +}`, + }, + { + long, + `"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"`, + }, + { + LongStructTypeName{ + longFieldName: LongStructTypeName{}, + otherLongFieldName: long, + }, + `pretty.LongStructTypeName{ + longFieldName: pretty.LongStructTypeName{}, + otherLongFieldName: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", +}`, + }, + { + &LongStructTypeName{ + longFieldName: &LongStructTypeName{}, + otherLongFieldName: (*LongStructTypeName)(nil), + }, + `&pretty.LongStructTypeName{ + longFieldName: &pretty.LongStructTypeName{}, + otherLongFieldName: (*pretty.LongStructTypeName)(nil), +}`, + }, + { + []LongStructTypeName{ + {nil, nil}, + {3, 3}, + {long, nil}, + }, + `[]pretty.LongStructTypeName{ + {}, + { + longFieldName: int(3), + otherLongFieldName: int(3), + }, + { + longFieldName: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + otherLongFieldName: nil, + }, +}`, + }, + { + []interface{}{ + LongStructTypeName{nil, nil}, + []byte{1, 2, 3}, + T{3, 4}, + LongStructTypeName{long, nil}, + }, + `[]interface {}{ + pretty.LongStructTypeName{}, + []uint8{0x1, 0x2, 0x3}, + pretty.T{x:3, y:4}, + pretty.LongStructTypeName{ + longFieldName: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + otherLongFieldName: nil, + }, +}`, + }, +} + +func TestGoSyntax(t *testing.T) { + for _, tt := range gosyntax { + s := fmt.Sprintf("%# v", Formatter(tt.v)) + if tt.s != s { + t.Errorf("expected %q", tt.s) + t.Errorf("got %q", s) + t.Errorf("expraw\n%s", tt.s) + t.Errorf("gotraw\n%s", s) + } + } +} + +type I struct { + i int + R interface{} +} + +func (i *I) I() *I { return i.R.(*I) } + +func TestCycle(t *testing.T) { + type A struct{ *A } + v := &A{} + v.A = v + + // panics from stack overflow without cycle detection + t.Logf("Example cycle:\n%# v", Formatter(v)) + + p := &A{} + s := fmt.Sprintf("%# v", Formatter([]*A{p, p})) + if strings.Contains(s, "CYCLIC") { + t.Errorf("Repeated address detected as cyclic reference:\n%s", s) + } + + type R struct { + i int + *R + } + r := &R{ + i: 1, + R: &R{ + i: 2, + R: &R{ + i: 3, + }, + }, + } + r.R.R.R = r + t.Logf("Example longer cycle:\n%# v", Formatter(r)) + + r = &R{ + i: 1, + R: &R{ + i: 2, + R: &R{ + i: 3, + R: &R{ + i: 4, + R: &R{ + i: 5, + R: &R{ + i: 6, + R: &R{ + i: 7, + R: &R{ + i: 8, + R: &R{ + i: 9, + R: &R{ + i: 10, + R: &R{ + i: 11, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + // here be pirates + r.R.R.R.R.R.R.R.R.R.R.R = r + t.Logf("Example very long cycle:\n%# v", Formatter(r)) + + i := &I{ + i: 1, + R: &I{ + i: 2, + R: &I{ + i: 3, + R: &I{ + i: 4, + R: &I{ + i: 5, + R: &I{ + i: 6, + R: &I{ + i: 7, + R: &I{ + i: 8, + R: &I{ + i: 9, + R: &I{ + i: 10, + R: &I{ + i: 11, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + iv := i.I().I().I().I().I().I().I().I().I().I() + *iv = *i + t.Logf("Example long interface cycle:\n%# v", Formatter(i)) +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/pretty.go b/Godeps/_workspace/src/github.com/kr/pretty/pretty.go new file mode 100644 index 00000000000..d3df8686ce8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/pretty.go @@ -0,0 +1,98 @@ +// Package pretty provides pretty-printing for Go values. This is +// useful during debugging, to avoid wrapping long output lines in +// the terminal. +// +// It provides a function, Formatter, that can be used with any +// function that accepts a format string. It also provides +// convenience wrappers for functions in packages fmt and log. +package pretty + +import ( + "fmt" + "io" + "log" +) + +// Errorf is a convenience wrapper for fmt.Errorf. +// +// Calling Errorf(f, x, y) is equivalent to +// fmt.Errorf(f, Formatter(x), Formatter(y)). +func Errorf(format string, a ...interface{}) error { + return fmt.Errorf(format, wrap(a, false)...) +} + +// Fprintf is a convenience wrapper for fmt.Fprintf. +// +// Calling Fprintf(w, f, x, y) is equivalent to +// fmt.Fprintf(w, f, Formatter(x), Formatter(y)). +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error error) { + return fmt.Fprintf(w, format, wrap(a, false)...) +} + +// Log is a convenience wrapper for log.Printf. +// +// Calling Log(x, y) is equivalent to +// log.Print(Formatter(x), Formatter(y)), but each operand is +// formatted with "%# v". +func Log(a ...interface{}) { + log.Print(wrap(a, true)...) +} + +// Logf is a convenience wrapper for log.Printf. +// +// Calling Logf(f, x, y) is equivalent to +// log.Printf(f, Formatter(x), Formatter(y)). +func Logf(format string, a ...interface{}) { + log.Printf(format, wrap(a, false)...) +} + +// Logln is a convenience wrapper for log.Printf. +// +// Calling Logln(x, y) is equivalent to +// log.Println(Formatter(x), Formatter(y)), but each operand is +// formatted with "%# v". +func Logln(a ...interface{}) { + log.Println(wrap(a, true)...) +} + +// Print pretty-prints its operands and writes to standard output. +// +// Calling Print(x, y) is equivalent to +// fmt.Print(Formatter(x), Formatter(y)), but each operand is +// formatted with "%# v". +func Print(a ...interface{}) (n int, errno error) { + return fmt.Print(wrap(a, true)...) +} + +// Printf is a convenience wrapper for fmt.Printf. +// +// Calling Printf(f, x, y) is equivalent to +// fmt.Printf(f, Formatter(x), Formatter(y)). +func Printf(format string, a ...interface{}) (n int, errno error) { + return fmt.Printf(format, wrap(a, false)...) +} + +// Println pretty-prints its operands and writes to standard output. +// +// Calling Print(x, y) is equivalent to +// fmt.Println(Formatter(x), Formatter(y)), but each operand is +// formatted with "%# v". +func Println(a ...interface{}) (n int, errno error) { + return fmt.Println(wrap(a, true)...) +} + +// Sprintf is a convenience wrapper for fmt.Sprintf. +// +// Calling Sprintf(f, x, y) is equivalent to +// fmt.Sprintf(f, Formatter(x), Formatter(y)). +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, wrap(a, false)...) +} + +func wrap(a []interface{}, force bool) []interface{} { + w := make([]interface{}, len(a)) + for i, x := range a { + w[i] = formatter{x: x, force: force} + } + return w +} diff --git a/Godeps/_workspace/src/github.com/kr/pretty/zero.go b/Godeps/_workspace/src/github.com/kr/pretty/zero.go new file mode 100644 index 00000000000..abb5b6fc14c --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/pretty/zero.go @@ -0,0 +1,41 @@ +package pretty + +import ( + "reflect" +) + +func nonzero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() != 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() != 0 + case reflect.Float32, reflect.Float64: + return v.Float() != 0 + case reflect.Complex64, reflect.Complex128: + return v.Complex() != complex(0, 0) + case reflect.String: + return v.String() != "" + case reflect.Struct: + for i := 0; i < v.NumField(); i++ { + if nonzero(getField(v, i)) { + return true + } + } + return false + case reflect.Array: + for i := 0; i < v.Len(); i++ { + if nonzero(v.Index(i)) { + return true + } + } + return false + case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func: + return !v.IsNil() + case reflect.UnsafePointer: + return v.Pointer() != 0 + } + return true +} diff --git a/Godeps/_workspace/src/github.com/kr/text/License b/Godeps/_workspace/src/github.com/kr/text/License new file mode 100644 index 00000000000..480a3280599 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/License @@ -0,0 +1,19 @@ +Copyright 2012 Keith Rarick + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/kr/text/Readme b/Godeps/_workspace/src/github.com/kr/text/Readme new file mode 100644 index 00000000000..7e6e7c0687b --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/Readme @@ -0,0 +1,3 @@ +This is a Go package for manipulating paragraphs of text. + +See http://go.pkgdoc.org/github.com/kr/text for full documentation. diff --git a/Godeps/_workspace/src/github.com/kr/text/colwriter/Readme b/Godeps/_workspace/src/github.com/kr/text/colwriter/Readme new file mode 100644 index 00000000000..1c1f4e68393 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/colwriter/Readme @@ -0,0 +1,5 @@ +Package colwriter provides a write filter that formats +input lines in multiple columns. + +The package is a straightforward translation from +/src/cmd/draw/mc.c in Plan 9 from User Space. diff --git a/Godeps/_workspace/src/github.com/kr/text/colwriter/column.go b/Godeps/_workspace/src/github.com/kr/text/colwriter/column.go new file mode 100644 index 00000000000..7302ce9f7a8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/colwriter/column.go @@ -0,0 +1,147 @@ +// Package colwriter provides a write filter that formats +// input lines in multiple columns. +// +// The package is a straightforward translation from +// /src/cmd/draw/mc.c in Plan 9 from User Space. +package colwriter + +import ( + "bytes" + "io" + "unicode/utf8" +) + +const ( + tab = 4 +) + +const ( + // Print each input line ending in a colon ':' separately. + BreakOnColon uint = 1 << iota +) + +// A Writer is a filter that arranges input lines in as many columns as will +// fit in its width. Tab '\t' chars in the input are translated to sequences +// of spaces ending at multiples of 4 positions. +// +// If BreakOnColon is set, each input line ending in a colon ':' is written +// separately. +// +// The Writer assumes that all Unicode code points have the same width; this +// may not be true in some fonts. +type Writer struct { + w io.Writer + buf []byte + width int + flag uint +} + +// NewWriter allocates and initializes a new Writer writing to w. +// Parameter width controls the total number of characters on each line +// across all columns. +func NewWriter(w io.Writer, width int, flag uint) *Writer { + return &Writer{ + w: w, + width: width, + flag: flag, + } +} + +// Write writes p to the writer w. The only errors returned are ones +// encountered while writing to the underlying output stream. +func (w *Writer) Write(p []byte) (n int, err error) { + var linelen int + var lastWasColon bool + for i, c := range p { + w.buf = append(w.buf, c) + linelen++ + if c == '\t' { + w.buf[len(w.buf)-1] = ' ' + for linelen%tab != 0 { + w.buf = append(w.buf, ' ') + linelen++ + } + } + if w.flag&BreakOnColon != 0 && c == ':' { + lastWasColon = true + } else if lastWasColon { + if c == '\n' { + pos := bytes.LastIndex(w.buf[:len(w.buf)-1], []byte{'\n'}) + if pos < 0 { + pos = 0 + } + line := w.buf[pos:] + w.buf = w.buf[:pos] + if err = w.columnate(); err != nil { + if len(line) < i { + return i - len(line), err + } + return 0, err + } + if n, err := w.w.Write(line); err != nil { + if r := len(line) - n; r < i { + return i - r, err + } + return 0, err + } + } + lastWasColon = false + } + if c == '\n' { + linelen = 0 + } + } + return len(p), nil +} + +// Flush should be called after the last call to Write to ensure that any data +// buffered in the Writer is written to output. +func (w *Writer) Flush() error { + return w.columnate() +} + +func (w *Writer) columnate() error { + words := bytes.Split(w.buf, []byte{'\n'}) + w.buf = nil + if len(words[len(words)-1]) == 0 { + words = words[:len(words)-1] + } + maxwidth := 0 + for _, wd := range words { + if n := utf8.RuneCount(wd); n > maxwidth { + maxwidth = n + } + } + maxwidth++ // space char + wordsPerLine := w.width / maxwidth + if wordsPerLine <= 0 { + wordsPerLine = 1 + } + nlines := (len(words) + wordsPerLine - 1) / wordsPerLine + for i := 0; i < nlines; i++ { + col := 0 + endcol := 0 + for j := i; j < len(words); j += nlines { + endcol += maxwidth + _, err := w.w.Write(words[j]) + if err != nil { + return err + } + col += utf8.RuneCount(words[j]) + if j+nlines < len(words) { + for col < endcol { + _, err := w.w.Write([]byte{' '}) + if err != nil { + return err + } + col++ + } + } + } + _, err := w.w.Write([]byte{'\n'}) + if err != nil { + return err + } + } + return nil +} diff --git a/Godeps/_workspace/src/github.com/kr/text/colwriter/column_test.go b/Godeps/_workspace/src/github.com/kr/text/colwriter/column_test.go new file mode 100644 index 00000000000..ce388f5a260 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/colwriter/column_test.go @@ -0,0 +1,90 @@ +package colwriter + +import ( + "bytes" + "testing" +) + +var src = ` +.git +.gitignore +.godir +Procfile: +README.md +api.go +apps.go +auth.go +darwin.go +data.go +dyno.go: +env.go +git.go +help.go +hkdist +linux.go +ls.go +main.go +plugin.go +run.go +scale.go +ssh.go +tail.go +term +unix.go +update.go +version.go +windows.go +`[1:] + +var tests = []struct { + wid int + flag uint + src string + want string +}{ + {80, 0, "", ""}, + {80, 0, src, ` +.git README.md darwin.go git.go ls.go scale.go unix.go +.gitignore api.go data.go help.go main.go ssh.go update.go +.godir apps.go dyno.go: hkdist plugin.go tail.go version.go +Procfile: auth.go env.go linux.go run.go term windows.go +`[1:]}, + {80, BreakOnColon, src, ` +.git .gitignore .godir + +Procfile: +README.md api.go apps.go auth.go darwin.go data.go + +dyno.go: +env.go hkdist main.go scale.go term version.go +git.go linux.go plugin.go ssh.go unix.go windows.go +help.go ls.go run.go tail.go update.go +`[1:]}, + {20, 0, ` +Hello +Γειά σου +안녕 +今日は +`[1:], ` +Hello 안녕 +Γειά σου 今日は +`[1:]}, +} + +func TestWriter(t *testing.T) { + for _, test := range tests { + b := new(bytes.Buffer) + w := NewWriter(b, test.wid, test.flag) + if _, err := w.Write([]byte(test.src)); err != nil { + t.Error(err) + } + if err := w.Flush(); err != nil { + t.Error(err) + } + if g := b.String(); test.want != g { + t.Log("\n" + test.want) + t.Log("\n" + g) + t.Errorf("%q != %q", test.want, g) + } + } +} diff --git a/Godeps/_workspace/src/github.com/kr/text/doc.go b/Godeps/_workspace/src/github.com/kr/text/doc.go new file mode 100644 index 00000000000..cf4c198f955 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/doc.go @@ -0,0 +1,3 @@ +// Package text provides rudimentary functions for manipulating text in +// paragraphs. +package text diff --git a/Godeps/_workspace/src/github.com/kr/text/indent.go b/Godeps/_workspace/src/github.com/kr/text/indent.go new file mode 100644 index 00000000000..4ebac45c092 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/indent.go @@ -0,0 +1,74 @@ +package text + +import ( + "io" +) + +// Indent inserts prefix at the beginning of each non-empty line of s. The +// end-of-line marker is NL. +func Indent(s, prefix string) string { + return string(IndentBytes([]byte(s), []byte(prefix))) +} + +// IndentBytes inserts prefix at the beginning of each non-empty line of b. +// The end-of-line marker is NL. +func IndentBytes(b, prefix []byte) []byte { + var res []byte + bol := true + for _, c := range b { + if bol && c != '\n' { + res = append(res, prefix...) + } + res = append(res, c) + bol = c == '\n' + } + return res +} + +// Writer indents each line of its input. +type indentWriter struct { + w io.Writer + bol bool + pre [][]byte + sel int + off int +} + +// NewIndentWriter makes a new write filter that indents the input +// lines. Each line is prefixed in order with the corresponding +// element of pre. If there are more lines than elements, the last +// element of pre is repeated for each subsequent line. +func NewIndentWriter(w io.Writer, pre ...[]byte) io.Writer { + return &indentWriter{ + w: w, + pre: pre, + bol: true, + } +} + +// The only errors returned are from the underlying indentWriter. +func (w *indentWriter) Write(p []byte) (n int, err error) { + for _, c := range p { + if w.bol { + var i int + i, err = w.w.Write(w.pre[w.sel][w.off:]) + w.off += i + if err != nil { + return n, err + } + } + _, err = w.w.Write([]byte{c}) + if err != nil { + return n, err + } + n++ + w.bol = c == '\n' + if w.bol { + w.off = 0 + if w.sel < len(w.pre)-1 { + w.sel++ + } + } + } + return n, nil +} diff --git a/Godeps/_workspace/src/github.com/kr/text/indent_test.go b/Godeps/_workspace/src/github.com/kr/text/indent_test.go new file mode 100644 index 00000000000..5c723eee855 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/indent_test.go @@ -0,0 +1,119 @@ +package text + +import ( + "bytes" + "testing" +) + +type T struct { + inp, exp, pre string +} + +var tests = []T{ + { + "The quick brown fox\njumps over the lazy\ndog.\nBut not quickly.\n", + "xxxThe quick brown fox\nxxxjumps over the lazy\nxxxdog.\nxxxBut not quickly.\n", + "xxx", + }, + { + "The quick brown fox\njumps over the lazy\ndog.\n\nBut not quickly.", + "xxxThe quick brown fox\nxxxjumps over the lazy\nxxxdog.\n\nxxxBut not quickly.", + "xxx", + }, +} + +func TestIndent(t *testing.T) { + for _, test := range tests { + got := Indent(test.inp, test.pre) + if got != test.exp { + t.Errorf("mismatch %q != %q", got, test.exp) + } + } +} + +type IndentWriterTest struct { + inp, exp string + pre []string +} + +var ts = []IndentWriterTest{ + { + ` +The quick brown fox +jumps over the lazy +dog. +But not quickly. +`[1:], + ` +xxxThe quick brown fox +xxxjumps over the lazy +xxxdog. +xxxBut not quickly. +`[1:], + []string{"xxx"}, + }, + { + ` +The quick brown fox +jumps over the lazy +dog. +But not quickly. +`[1:], + ` +xxaThe quick brown fox +xxxjumps over the lazy +xxxdog. +xxxBut not quickly. +`[1:], + []string{"xxa", "xxx"}, + }, + { + ` +The quick brown fox +jumps over the lazy +dog. +But not quickly. +`[1:], + ` +xxaThe quick brown fox +xxbjumps over the lazy +xxcdog. +xxxBut not quickly. +`[1:], + []string{"xxa", "xxb", "xxc", "xxx"}, + }, + { + ` +The quick brown fox +jumps over the lazy +dog. + +But not quickly.`[1:], + ` +xxaThe quick brown fox +xxxjumps over the lazy +xxxdog. +xxx +xxxBut not quickly.`[1:], + []string{"xxa", "xxx"}, + }, +} + +func TestIndentWriter(t *testing.T) { + for _, test := range ts { + b := new(bytes.Buffer) + pre := make([][]byte, len(test.pre)) + for i := range test.pre { + pre[i] = []byte(test.pre[i]) + } + w := NewIndentWriter(b, pre...) + if _, err := w.Write([]byte(test.inp)); err != nil { + t.Error(err) + } + if got := b.String(); got != test.exp { + t.Errorf("mismatch %q != %q", got, test.exp) + t.Log(got) + t.Log(test.exp) + } + } +} diff --git a/Godeps/_workspace/src/github.com/kr/text/mc/Readme b/Godeps/_workspace/src/github.com/kr/text/mc/Readme new file mode 100644 index 00000000000..519ddc00a13 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/mc/Readme @@ -0,0 +1,9 @@ +Command mc prints in multiple columns. + + Usage: mc [-] [-N] [file...] + +Mc splits the input into as many columns as will fit in N +print positions. If the output is a tty, the default N is +the number of characters in a terminal line; otherwise the +default N is 80. Under option - each input line ending in +a colon ':' is printed separately. diff --git a/Godeps/_workspace/src/github.com/kr/text/mc/mc.go b/Godeps/_workspace/src/github.com/kr/text/mc/mc.go new file mode 100644 index 00000000000..00169a30f16 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/mc/mc.go @@ -0,0 +1,62 @@ +// Command mc prints in multiple columns. +// +// Usage: mc [-] [-N] [file...] +// +// Mc splits the input into as many columns as will fit in N +// print positions. If the output is a tty, the default N is +// the number of characters in a terminal line; otherwise the +// default N is 80. Under option - each input line ending in +// a colon ':' is printed separately. +package main + +import ( + "github.com/kr/pty" + "github.com/kr/text/colwriter" + "io" + "log" + "os" + "strconv" +) + +func main() { + var width int + var flag uint + args := os.Args[1:] + for len(args) > 0 && len(args[0]) > 0 && args[0][0] == '-' { + if len(args[0]) > 1 { + width, _ = strconv.Atoi(args[0][1:]) + } else { + flag |= colwriter.BreakOnColon + } + args = args[1:] + } + if width < 1 { + _, width, _ = pty.Getsize(os.Stdout) + } + if width < 1 { + width = 80 + } + + w := colwriter.NewWriter(os.Stdout, width, flag) + if len(args) > 0 { + for _, s := range args { + if f, err := os.Open(s); err == nil { + copyin(w, f) + f.Close() + } else { + log.Println(err) + } + } + } else { + copyin(w, os.Stdin) + } +} + +func copyin(w *colwriter.Writer, r io.Reader) { + if _, err := io.Copy(w, r); err != nil { + log.Println(err) + } + if err := w.Flush(); err != nil { + log.Println(err) + } +} diff --git a/Godeps/_workspace/src/github.com/kr/text/wrap.go b/Godeps/_workspace/src/github.com/kr/text/wrap.go new file mode 100644 index 00000000000..b09bb03736d --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/wrap.go @@ -0,0 +1,86 @@ +package text + +import ( + "bytes" + "math" +) + +var ( + nl = []byte{'\n'} + sp = []byte{' '} +) + +const defaultPenalty = 1e5 + +// Wrap wraps s into a paragraph of lines of length lim, with minimal +// raggedness. +func Wrap(s string, lim int) string { + return string(WrapBytes([]byte(s), lim)) +} + +// WrapBytes wraps b into a paragraph of lines of length lim, with minimal +// raggedness. +func WrapBytes(b []byte, lim int) []byte { + words := bytes.Split(bytes.Replace(bytes.TrimSpace(b), nl, sp, -1), sp) + var lines [][]byte + for _, line := range WrapWords(words, 1, lim, defaultPenalty) { + lines = append(lines, bytes.Join(line, sp)) + } + return bytes.Join(lines, nl) +} + +// WrapWords is the low-level line-breaking algorithm, useful if you need more +// control over the details of the text wrapping process. For most uses, either +// Wrap or WrapBytes will be sufficient and more convenient. +// +// WrapWords splits a list of words into lines with minimal "raggedness", +// treating each byte as one unit, accounting for spc units between adjacent +// words on each line, and attempting to limit lines to lim units. Raggedness +// is the total error over all lines, where error is the square of the +// difference of the length of the line and lim. Too-long lines (which only +// happen when a single word is longer than lim units) have pen penalty units +// added to the error. +func WrapWords(words [][]byte, spc, lim, pen int) [][][]byte { + n := len(words) + + length := make([][]int, n) + for i := 0; i < n; i++ { + length[i] = make([]int, n) + length[i][i] = len(words[i]) + for j := i + 1; j < n; j++ { + length[i][j] = length[i][j-1] + spc + len(words[j]) + } + } + + nbrk := make([]int, n) + cost := make([]int, n) + for i := range cost { + cost[i] = math.MaxInt32 + } + for i := n - 1; i >= 0; i-- { + if length[i][n-1] <= lim || i == n-1 { + cost[i] = 0 + nbrk[i] = n + } else { + for j := i + 1; j < n; j++ { + d := lim - length[i][j-1] + c := d*d + cost[j] + if length[i][j-1] > lim { + c += pen // too-long lines get a worse penalty + } + if c < cost[i] { + cost[i] = c + nbrk[i] = j + } + } + } + } + + var lines [][][]byte + i := 0 + for i < n { + lines = append(lines, words[i:nbrk[i]]) + i = nbrk[i] + } + return lines +} diff --git a/Godeps/_workspace/src/github.com/kr/text/wrap_test.go b/Godeps/_workspace/src/github.com/kr/text/wrap_test.go new file mode 100644 index 00000000000..634b6e8ebb9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/kr/text/wrap_test.go @@ -0,0 +1,62 @@ +package text + +import ( + "bytes" + "testing" +) + +var text = "The quick brown fox jumps over the lazy dog." + +func TestWrap(t *testing.T) { + exp := [][]string{ + {"The", "quick", "brown", "fox"}, + {"jumps", "over", "the", "lazy", "dog."}, + } + words := bytes.Split([]byte(text), sp) + got := WrapWords(words, 1, 24, defaultPenalty) + if len(exp) != len(got) { + t.Fail() + } + for i := range exp { + if len(exp[i]) != len(got[i]) { + t.Fail() + } + for j := range exp[i] { + if exp[i][j] != string(got[i][j]) { + t.Fatal(i, exp[i][j], got[i][j]) + } + } + } +} + +func TestWrapNarrow(t *testing.T) { + exp := "The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog." + if Wrap(text, 5) != exp { + t.Fail() + } +} + +func TestWrapOneLine(t *testing.T) { + exp := "The quick brown fox jumps over the lazy dog." + if Wrap(text, 500) != exp { + t.Fail() + } +} + +func TestWrapBug1(t *testing.T) { + cases := []struct { + limit int + text string + want string + }{ + {4, "aaaaa", "aaaaa"}, + {4, "a aaaaa", "a\naaaaa"}, + } + + for _, test := range cases { + got := Wrap(test.text, test.limit) + if got != test.want { + t.Errorf("Wrap(%q, %d) = %q want %q", test.text, test.limit, got, test.want) + } + } +} From 40b2f00dc5b1dfee5800b292c3bd894747e365c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 11 Mar 2016 23:39:42 +0100 Subject: [PATCH 06/33] fix(): fixed from db -> json --- pkg/components/simplejson/simplejson.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/components/simplejson/simplejson.go b/pkg/components/simplejson/simplejson.go index 1ea8aa346aa..2a96d06d694 100644 --- a/pkg/components/simplejson/simplejson.go +++ b/pkg/components/simplejson/simplejson.go @@ -26,6 +26,10 @@ func (j *Json) FromDB(data []byte) error { } func (j *Json) ToDB() ([]byte, error) { + if j == nil || j.data == nil { + return nil, nil + } + return j.Encode() } From 3fb0b71822bf7f7a1943acd88efe9fd965561dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 12 Mar 2016 00:13:06 +0100 Subject: [PATCH 07/33] refactor(): refactoring json usage --- pkg/components/simplejson/simplejson.go | 7 +++- pkg/models/dashboards.go | 52 ++++++++++--------------- pkg/models/dashboards_test.go | 8 ++-- pkg/plugins/dashboard_importer.go | 46 +++++++++++----------- pkg/plugins/dashboard_importer_test.go | 23 +++++------ pkg/plugins/dashboards.go | 8 ++-- pkg/plugins/dashboards_test.go | 2 +- pkg/services/search/json_index.go | 8 ++-- 8 files changed, 68 insertions(+), 86 deletions(-) diff --git a/pkg/components/simplejson/simplejson.go b/pkg/components/simplejson/simplejson.go index 2a96d06d694..85e2f955943 100644 --- a/pkg/components/simplejson/simplejson.go +++ b/pkg/components/simplejson/simplejson.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "errors" - "fmt" "log" ) @@ -51,6 +50,11 @@ func New() *Json { } } +// New returns a pointer to a new, empty `Json` object +func NewFromAny(data interface{}) *Json { + return &Json{data: data} +} + // Interface returns the underlying data func (j *Json) Interface() interface{} { return j.data @@ -68,7 +72,6 @@ func (j *Json) EncodePretty() ([]byte, error) { // Implements the json.Marshaler interface. func (j *Json) MarshalJSON() ([]byte, error) { - fmt.Printf("MarshalJSON") return json.Marshal(&j.data) } diff --git a/pkg/models/dashboards.go b/pkg/models/dashboards.go index 3e87f504a77..6243c729624 100644 --- a/pkg/models/dashboards.go +++ b/pkg/models/dashboards.go @@ -6,6 +6,7 @@ import ( "time" "github.com/gosimple/slug" + "github.com/grafana/grafana/pkg/components/simplejson" ) // Typed errors @@ -37,14 +38,14 @@ type Dashboard struct { CreatedBy int64 Title string - Data map[string]interface{} + Data *simplejson.Json } // NewDashboard creates a new dashboard func NewDashboard(title string) *Dashboard { dash := &Dashboard{} - dash.Data = make(map[string]interface{}) - dash.Data["title"] = title + dash.Data = simplejson.New() + dash.Data.Set("title", title) dash.Title = title dash.Created = time.Now() dash.Updated = time.Now() @@ -54,34 +55,24 @@ func NewDashboard(title string) *Dashboard { // GetTags turns the tags in data json into go string array func (dash *Dashboard) GetTags() []string { - jsonTags := dash.Data["tags"] - if jsonTags == nil || jsonTags == "" { - return []string{} - } - - arr := jsonTags.([]interface{}) - b := make([]string, len(arr)) - for i := range arr { - b[i] = arr[i].(string) - } - return b + return dash.Data.Get("tags").MustStringArray() } -func NewDashboardFromJson(data map[string]interface{}) *Dashboard { +func NewDashboardFromJson(data *simplejson.Json) *Dashboard { dash := &Dashboard{} dash.Data = data - dash.Title = dash.Data["title"].(string) + dash.Title = dash.Data.Get("title").MustString() dash.UpdateSlug() - if dash.Data["id"] != nil { - dash.Id = int64(dash.Data["id"].(float64)) + if id, err := dash.Data.Get("id").Float64(); err == nil { + dash.Id = int64(id) - if dash.Data["version"] != nil { - dash.Version = int(dash.Data["version"].(float64)) + if version, err := dash.Data.Get("version").Float64(); err == nil { + dash.Version = int(version) dash.Updated = time.Now() } } else { - dash.Data["version"] = 0 + dash.Data.Set("version", 0) dash.Created = time.Now() dash.Updated = time.Now() } @@ -92,9 +83,11 @@ func NewDashboardFromJson(data map[string]interface{}) *Dashboard { // GetDashboardModel turns the command into the savable model func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard { dash := NewDashboardFromJson(cmd.Dashboard) - if dash.Data["version"] == 0 { + + if dash.Data.Get("version").MustInt(0) == 0 { dash.CreatedBy = cmd.UserId } + dash.UpdatedBy = cmd.UserId dash.OrgId = cmd.OrgId dash.UpdateSlug() @@ -103,15 +96,12 @@ func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard { // GetString a func (dash *Dashboard) GetString(prop string, defaultValue string) string { - if val, exists := dash.Data[prop]; exists { - return val.(string) - } - return defaultValue + return dash.Data.Get(prop).MustString(defaultValue) } // UpdateSlug updates the slug func (dash *Dashboard) UpdateSlug() { - title := strings.ToLower(dash.Data["title"].(string)) + title := strings.ToLower(dash.Data.Get("title").MustString()) dash.Slug = slug.Make(title) } @@ -120,10 +110,10 @@ func (dash *Dashboard) UpdateSlug() { // type SaveDashboardCommand struct { - Dashboard map[string]interface{} `json:"dashboard" binding:"Required"` - UserId int64 `json:"userId"` - OrgId int64 `json:"-"` - Overwrite bool `json:"overwrite"` + Dashboard *simplejson.Json `json:"dashboard" binding:"Required"` + UserId int64 `json:"userId"` + OrgId int64 `json:"-"` + Overwrite bool `json:"overwrite"` Result *Dashboard } diff --git a/pkg/models/dashboards_test.go b/pkg/models/dashboards_test.go index b0b6796c4d8..ee16508dc8a 100644 --- a/pkg/models/dashboards_test.go +++ b/pkg/models/dashboards_test.go @@ -3,6 +3,7 @@ package models import ( "testing" + "github.com/grafana/grafana/pkg/components/simplejson" . "github.com/smartystreets/goconvey/convey" ) @@ -16,12 +17,11 @@ func TestDashboardModel(t *testing.T) { }) Convey("Given a dashboard json", t, func() { - json := map[string]interface{}{ - "title": "test dash", - } + json := simplejson.New() + json.Set("title", "test dash") Convey("With tags as string value", func() { - json["tags"] = "" + json.Set("tags", "") dash := NewDashboardFromJson(json) So(len(dash.GetTags()), ShouldEqual, 0) diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index 15e055faffd..2a640e814e9 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -6,7 +6,7 @@ import ( "regexp" "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/components/dynmap" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/log" m "github.com/grafana/grafana/pkg/models" ) @@ -54,9 +54,8 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { return err } - template := dynmap.NewFromMap(dashboard.Data) evaluator := &DashTemplateEvaluator{ - template: template, + template: dashboard.Data, inputs: cmd.Inputs, } @@ -66,7 +65,7 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { } saveCmd := m.SaveDashboardCommand{ - Dashboard: generatedDash.StringMap(), + Dashboard: generatedDash, OrgId: cmd.OrgId, UserId: cmd.UserId, } @@ -89,15 +88,15 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { } type DashTemplateEvaluator struct { - template *dynmap.Object + template *simplejson.Json inputs []ImportDashboardInput variables map[string]string - result *dynmap.Object + result *simplejson.Json varRegex *regexp.Regexp } -func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Object) *ImportDashboardInput { - inputType, _ := varDef.GetString("type") +func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson.Json) *ImportDashboardInput { + inputType := varDef.Get("type").MustString() for _, input := range this.inputs { if inputType == input.Type && (input.Name == varName || input.Name == "*") { @@ -108,16 +107,15 @@ func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Obje return nil } -func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) { - this.result = dynmap.NewObject() +func (this *DashTemplateEvaluator) Eval() (*simplejson.Json, error) { + this.result = simplejson.New() this.variables = make(map[string]string) this.varRegex, _ = regexp.Compile("\\$__(\\w+)") // check that we have all inputs we need - if requiredInputs, err := this.template.GetObject("__inputs"); err == nil { - for varName, value := range requiredInputs.Map() { - varDef, _ := value.Object() - input := this.findInput(varName, varDef) + if inputDefs := this.template.Get("__inputs"); inputDefs != nil { + for varName, value := range inputDefs.MustMap() { + input := this.findInput(varName, simplejson.NewFromAny(value)) if input == nil { return nil, &DashboardInputMissingError{VariableName: varName} @@ -133,28 +131,28 @@ func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) { return this.result, nil } -func (this *DashTemplateEvaluator) EvalObject(source *dynmap.Object, writer *dynmap.Object) { +func (this *DashTemplateEvaluator) EvalObject(source *simplejson.Json, writer *simplejson.Json) { - for key, value := range source.Map() { + for key, value := range source.MustMap() { if key == "__inputs" { continue } - goValue := value.Interface() - - switch v := goValue.(type) { + switch v := value.(type) { case string: interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string { return this.variables[match] }) - writer.SetValue(key, interpolated) + writer.Set(key, interpolated) case map[string]interface{}: - childSource, _ := value.Object() - childWriter, _ := writer.SetValue(key, map[string]interface{}{}).Object() + childSource := simplejson.NewFromAny(value) + childWriter := simplejson.New() + writer.Set(key, childWriter.Interface()) this.EvalObject(childSource, childWriter) + case []interface{}: default: - log.Info("type: %v", reflect.TypeOf(goValue)) - log.Error(3, "Unknown json type key: %v , type: %v", key, goValue) + log.Info("type: %v", reflect.TypeOf(value)) + log.Error(3, "Unknown json type key: %v , type: %v", key, value) } } } diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go index 472de6b4e26..3e4c307cbb9 100644 --- a/pkg/plugins/dashboard_importer_test.go +++ b/pkg/plugins/dashboard_importer_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/components/dynmap" + "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" . "github.com/smartystreets/goconvey/convey" @@ -44,21 +44,16 @@ func TestDashboardImport(t *testing.T) { Convey("should install dashboard", func() { So(importedDash, ShouldNotBeNil) - dashData := dynmap.NewFromMap(importedDash.Data) - So(dashData.String(), ShouldEqual, "") + dashStr, _ := importedDash.Data.EncodePretty() + So(string(dashStr), ShouldEqual, "") - rows := importedDash.Data["rows"].([]interface{}) - row1 := rows[0].(map[string]interface{}) - panels := row1["panels"].([]interface{}) - panel := panels[0].(map[string]interface{}) - - So(panel["datasource"], ShouldEqual, "graphite") - So(importedDash.Data["__inputs"], ShouldBeNil) + // So(panel["datasource"], ShouldEqual, "graphite") + // So(importedDash.Data["__inputs"], ShouldBeNil) }) }) Convey("When evaling dashboard template", t, func() { - template, _ := dynmap.NewObjectFromBytes([]byte(`{ + template, _ := simplejson.NewJson([]byte(`{ "__inputs": { "graphite": { "type": "datasource" @@ -80,12 +75,12 @@ func TestDashboardImport(t *testing.T) { So(err, ShouldBeNil) Convey("should render template", func() { - So(res.MustGetString("test.prop", ""), ShouldEqual, "my-server") + So(res.GetPath("test", "prop").MustString(), ShouldEqual, "my-server") }) Convey("should not include inputs in output", func() { - _, err := res.GetObject("__inputs") - So(err, ShouldNotBeNil) + inputs := res.Get("__inputs") + So(inputs.Interface(), ShouldBeNil) }) }) diff --git a/pkg/plugins/dashboards.go b/pkg/plugins/dashboards.go index 1697ad808f2..932196a42a9 100644 --- a/pkg/plugins/dashboards.go +++ b/pkg/plugins/dashboards.go @@ -1,11 +1,11 @@ package plugins import ( - "encoding/json" "os" "path/filepath" "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" ) @@ -52,10 +52,8 @@ func loadPluginDashboard(plugin *PluginBase, path string) (*m.Dashboard, error) defer reader.Close() - jsonParser := json.NewDecoder(reader) - var data map[string]interface{} - - if err := jsonParser.Decode(&data); err != nil { + data, err := simplejson.NewFromReader(reader) + if err != nil { return nil, err } diff --git a/pkg/plugins/dashboards_test.go b/pkg/plugins/dashboards_test.go index 58cbe2f4920..bdd08ceefd2 100644 --- a/pkg/plugins/dashboards_test.go +++ b/pkg/plugins/dashboards_test.go @@ -23,7 +23,7 @@ func TestPluginDashboards(t *testing.T) { bus.AddHandler("test", func(query *m.GetDashboardQuery) error { if query.Slug == "nginx-connections" { dash := m.NewDashboard("Nginx Connections") - dash.Data["revision"] = "1.1" + dash.Data.Set("revision", "1.1") query.Result = dash return nil } diff --git a/pkg/services/search/json_index.go b/pkg/services/search/json_index.go index e70c662438d..79c238b27f9 100644 --- a/pkg/services/search/json_index.go +++ b/pkg/services/search/json_index.go @@ -1,12 +1,12 @@ package search import ( - "encoding/json" "os" "path/filepath" "strings" "time" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/log" m "github.com/grafana/grafana/pkg/models" ) @@ -120,10 +120,8 @@ func loadDashboardFromFile(filename string) (*JsonDashIndexItem, error) { } defer reader.Close() - jsonParser := json.NewDecoder(reader) - var data map[string]interface{} - - if err := jsonParser.Decode(&data); err != nil { + data, err := simplejson.NewFromReader(reader) + if err != nil { return nil, err } From 28f4f3a8c884217d950fd1a0282b70385f3218f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 12 Mar 2016 00:16:08 +0100 Subject: [PATCH 08/33] fix(datasource edit): Editing datasources broken earlier today, fixes #4343 --- public/app/features/plugins/ds_edit_ctrl.ts | 3 ++- public/app/features/plugins/partials/ds_edit.html | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/public/app/features/plugins/ds_edit_ctrl.ts b/public/app/features/plugins/ds_edit_ctrl.ts index 1e07b3a814a..d2ca7a82dc4 100644 --- a/public/app/features/plugins/ds_edit_ctrl.ts +++ b/public/app/features/plugins/ds_edit_ctrl.ts @@ -24,6 +24,7 @@ export class DataSourceEditCtrl { datasourceMeta: any; tabIndex: number; hasDashboards: boolean; + editForm: any; /** @ngInject */ constructor( @@ -114,7 +115,7 @@ export class DataSourceEditCtrl { } saveChanges(test) { - if (!this.$scope.editForm.$valid) { + if (!this.editForm.$valid) { return; } diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index 46177d998cc..4024b77b2c4 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -25,7 +25,7 @@
- +
Name @@ -52,12 +52,12 @@ -
-
Testing....
-
Test results
-
-
{{testing.title}}
-
+
+
Testing....
+
Test results
+
+
{{ctrl.testing.title}}
+
From 0398face05aac33ed42453570b919e9a125c32ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 12 Mar 2016 10:13:49 +0100 Subject: [PATCH 09/33] feat(plugins): dashboard import for data sources is working! #4298 --- pkg/api/dashboard_snapshot.go | 2 - pkg/api/dtos/models.go | 4 +- pkg/components/simplejson/simplejson_go11.go | 2 - pkg/models/dashboard_snapshot.go | 14 +- pkg/plugins/dashboard_importer.go | 55 +++--- pkg/plugins/dashboard_importer_test.go | 15 +- pkg/services/sqlstore/dashboard.go | 4 +- .../sqlstore/dashboard_snapshot_test.go | 7 +- pkg/services/sqlstore/dashboard_test.go | 17 +- .../app/features/dashboard/dashnav/dashnav.ts | 4 +- .../plugins/import_list/import_list.html | 6 +- .../plugins/import_list/import_list.ts | 2 +- .../features/plugins/partials/ds_edit.html | 2 +- .../graphite/dashboards/carbon_metrics.json | 176 ++++++++++++++++++ .../graphite/dashboards/carbon_stats.json | 22 --- .../plugins/datasource/graphite/plugin.json | 2 +- tests/test-app/dashboards/connections.json | 4 + .../dashboards/connections_result.json | 20 ++ 18 files changed, 278 insertions(+), 80 deletions(-) create mode 100644 public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json delete mode 100644 public/app/plugins/datasource/graphite/dashboards/carbon_stats.json create mode 100644 tests/test-app/dashboards/connections_result.json diff --git a/pkg/api/dashboard_snapshot.go b/pkg/api/dashboard_snapshot.go index 8ed848a7b11..3c369ca5b7f 100644 --- a/pkg/api/dashboard_snapshot.go +++ b/pkg/api/dashboard_snapshot.go @@ -53,7 +53,6 @@ func CreateDashboardSnapshot(c *middleware.Context, cmd m.CreateDashboardSnapsho } func GetDashboardSnapshot(c *middleware.Context) { - key := c.Params(":key") query := &m.GetDashboardSnapshotQuery{Key: key} @@ -136,5 +135,4 @@ func SearchDashboardSnapshots(c *middleware.Context) Response { } return Json(200, dtos) - //return Json(200, searchQuery.Result) } diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index d5534ea6ed4..26295dd3d3c 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -53,8 +53,8 @@ type DashboardMeta struct { } type DashboardFullWithMeta struct { - Meta DashboardMeta `json:"meta"` - Dashboard map[string]interface{} `json:"dashboard"` + Meta DashboardMeta `json:"meta"` + Dashboard *simplejson.Json `json:"dashboard"` } type DataSource struct { diff --git a/pkg/components/simplejson/simplejson_go11.go b/pkg/components/simplejson/simplejson_go11.go index 3a88b29e449..1c479532cf0 100644 --- a/pkg/components/simplejson/simplejson_go11.go +++ b/pkg/components/simplejson/simplejson_go11.go @@ -6,7 +6,6 @@ import ( "bytes" "encoding/json" "errors" - "fmt" "io" "reflect" "strconv" @@ -14,7 +13,6 @@ import ( // Implements the json.Unmarshaler interface. func (j *Json) UnmarshalJSON(p []byte) error { - fmt.Printf("UnmarshalJSON") dec := json.NewDecoder(bytes.NewBuffer(p)) dec.UseNumber() return dec.Decode(&j.data) diff --git a/pkg/models/dashboard_snapshot.go b/pkg/models/dashboard_snapshot.go index 9bfbd06c1ef..f920e91f2e4 100644 --- a/pkg/models/dashboard_snapshot.go +++ b/pkg/models/dashboard_snapshot.go @@ -1,6 +1,10 @@ package models -import "time" +import ( + "time" + + "github.com/grafana/grafana/pkg/components/simplejson" +) // DashboardSnapshot model type DashboardSnapshot struct { @@ -17,7 +21,7 @@ type DashboardSnapshot struct { Created time.Time Updated time.Time - Dashboard map[string]interface{} + Dashboard *simplejson.Json } // DashboardSnapshotDTO without dashboard map @@ -40,9 +44,9 @@ type DashboardSnapshotDTO struct { // COMMANDS type CreateDashboardSnapshotCommand struct { - Dashboard map[string]interface{} `json:"dashboard" binding:"Required"` - Name string `json:"name" binding:"Required"` - Expires int64 `json:"expires"` + Dashboard *simplejson.Json `json:"dashboard" binding:"Required"` + Name string `json:"name" binding:"Required"` + Expires int64 `json:"expires"` // these are passed when storing an external snapshot ref External bool `json:"external"` diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index 2a640e814e9..b5dc286f6d1 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -1,8 +1,8 @@ package plugins import ( + "encoding/json" "fmt" - "reflect" "regexp" "github.com/grafana/grafana/pkg/bus" @@ -127,32 +127,45 @@ func (this *DashTemplateEvaluator) Eval() (*simplejson.Json, error) { log.Info("Import: dashboard has no __import section") } - this.EvalObject(this.template, this.result) - return this.result, nil + return simplejson.NewFromAny(this.evalObject(this.template)), nil } -func (this *DashTemplateEvaluator) EvalObject(source *simplejson.Json, writer *simplejson.Json) { +func (this *DashTemplateEvaluator) evalValue(source *simplejson.Json) interface{} { + + sourceValue := source.Interface() + + switch v := sourceValue.(type) { + case string: + interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string { + return this.variables[match] + }) + return interpolated + case bool: + return v + case json.Number: + return v + case map[string]interface{}: + return this.evalObject(source) + case []interface{}: + array := make([]interface{}, 0) + for _, item := range v { + array = append(array, this.evalValue(simplejson.NewFromAny(item))) + } + return array + } + + return nil +} + +func (this *DashTemplateEvaluator) evalObject(source *simplejson.Json) interface{} { + result := make(map[string]interface{}) for key, value := range source.MustMap() { if key == "__inputs" { continue } - - switch v := value.(type) { - case string: - interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string { - return this.variables[match] - }) - writer.Set(key, interpolated) - case map[string]interface{}: - childSource := simplejson.NewFromAny(value) - childWriter := simplejson.New() - writer.Set(key, childWriter.Interface()) - this.EvalObject(childSource, childWriter) - case []interface{}: - default: - log.Info("type: %v", reflect.TypeOf(value)) - log.Error(3, "Unknown json type key: %v , type: %v", key, value) - } + result[key] = this.evalValue(simplejson.NewFromAny(value)) } + + return result } diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go index 3e4c307cbb9..9b5605277d4 100644 --- a/pkg/plugins/dashboard_importer_test.go +++ b/pkg/plugins/dashboard_importer_test.go @@ -1,6 +1,7 @@ package plugins import ( + "io/ioutil" "testing" "github.com/grafana/grafana/pkg/bus" @@ -34,7 +35,7 @@ func TestDashboardImport(t *testing.T) { OrgId: 1, UserId: 1, Inputs: []ImportDashboardInput{ - {Name: "*", Type: "datasource"}, + {Name: "*", Type: "datasource", Value: "graphite"}, }, } @@ -44,11 +45,15 @@ func TestDashboardImport(t *testing.T) { Convey("should install dashboard", func() { So(importedDash, ShouldNotBeNil) - dashStr, _ := importedDash.Data.EncodePretty() - So(string(dashStr), ShouldEqual, "") + resultStr, _ := importedDash.Data.EncodePretty() + expectedBytes, _ := ioutil.ReadFile("../../tests/test-app/dashboards/connections_result.json") + expectedJson, _ := simplejson.NewJson(expectedBytes) + expectedStr, _ := expectedJson.EncodePretty() - // So(panel["datasource"], ShouldEqual, "graphite") - // So(importedDash.Data["__inputs"], ShouldBeNil) + So(string(resultStr), ShouldEqual, string(expectedStr)) + + panel := importedDash.Data.Get("rows").GetIndex(0).Get("panels").GetIndex(0) + So(panel.Get("datasource").MustString(), ShouldEqual, "graphite") }) }) diff --git a/pkg/services/sqlstore/dashboard.go b/pkg/services/sqlstore/dashboard.go index a33ef10d725..396d507cfd2 100644 --- a/pkg/services/sqlstore/dashboard.go +++ b/pkg/services/sqlstore/dashboard.go @@ -69,7 +69,7 @@ func SaveDashboard(cmd *m.SaveDashboardCommand) error { affectedRows, err = sess.Insert(dash) } else { dash.Version += 1 - dash.Data["version"] = dash.Version + dash.Data.Set("version", dash.Version) affectedRows, err = sess.Id(dash.Id).Update(dash) } @@ -108,7 +108,7 @@ func GetDashboard(query *m.GetDashboardQuery) error { return m.ErrDashboardNotFound } - dashboard.Data["id"] = dashboard.Id + dashboard.Data.Set("id", dashboard.Id) query.Result = &dashboard return nil diff --git a/pkg/services/sqlstore/dashboard_snapshot_test.go b/pkg/services/sqlstore/dashboard_snapshot_test.go index 5301f0f1cc9..50375088b4b 100644 --- a/pkg/services/sqlstore/dashboard_snapshot_test.go +++ b/pkg/services/sqlstore/dashboard_snapshot_test.go @@ -5,6 +5,7 @@ import ( . "github.com/smartystreets/goconvey/convey" + "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" ) @@ -16,9 +17,9 @@ func TestDashboardSnapshotDBAccess(t *testing.T) { Convey("Given saved snaphot", func() { cmd := m.CreateDashboardSnapshotCommand{ Key: "hej", - Dashboard: map[string]interface{}{ + Dashboard: simplejson.NewFromAny(map[string]interface{}{ "hello": "mupp", - }, + }), } err := CreateDashboardSnapshot(&cmd) So(err, ShouldBeNil) @@ -29,7 +30,7 @@ func TestDashboardSnapshotDBAccess(t *testing.T) { So(err, ShouldBeNil) So(query.Result, ShouldNotBeNil) - So(query.Result.Dashboard["hello"], ShouldEqual, "mupp") + So(query.Result.Dashboard.Get("hello").MustString(), ShouldEqual, "mupp") }) }) diff --git a/pkg/services/sqlstore/dashboard_test.go b/pkg/services/sqlstore/dashboard_test.go index 2d35a0742de..609639f7788 100644 --- a/pkg/services/sqlstore/dashboard_test.go +++ b/pkg/services/sqlstore/dashboard_test.go @@ -5,6 +5,7 @@ import ( . "github.com/smartystreets/goconvey/convey" + "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/search" ) @@ -12,11 +13,11 @@ import ( func insertTestDashboard(title string, orgId int64, tags ...interface{}) *m.Dashboard { cmd := m.SaveDashboardCommand{ OrgId: orgId, - Dashboard: map[string]interface{}{ + Dashboard: simplejson.NewFromAny(map[string]interface{}{ "id": nil, "title": title, "tags": tags, - }, + }), } err := SaveDashboard(&cmd) @@ -58,11 +59,11 @@ func TestDashboardDataAccess(t *testing.T) { cmd := m.SaveDashboardCommand{ OrgId: 1, Overwrite: true, - Dashboard: map[string]interface{}{ + Dashboard: simplejson.NewFromAny(map[string]interface{}{ "id": float64(123412321), "title": "Expect error", "tags": []interface{}{}, - }, + }), } err := SaveDashboard(&cmd) @@ -76,11 +77,11 @@ func TestDashboardDataAccess(t *testing.T) { cmd := m.SaveDashboardCommand{ OrgId: 2, Overwrite: true, - Dashboard: map[string]interface{}{ + Dashboard: simplejson.NewFromAny(map[string]interface{}{ "id": float64(query.Result.Id), "title": "Expect error", "tags": []interface{}{}, - }, + }), } err := SaveDashboard(&cmd) @@ -135,11 +136,11 @@ func TestDashboardDataAccess(t *testing.T) { Convey("Should not be able to save dashboard with same name", func() { cmd := m.SaveDashboardCommand{ OrgId: 1, - Dashboard: map[string]interface{}{ + Dashboard: simplejson.NewFromAny(map[string]interface{}{ "id": nil, "title": "test dash 23", "tags": []interface{}{}, - }, + }), } err := SaveDashboard(&cmd) diff --git a/public/app/features/dashboard/dashnav/dashnav.ts b/public/app/features/dashboard/dashnav/dashnav.ts index dcc2f40d0dc..2d5b66cb13c 100644 --- a/public/app/features/dashboard/dashnav/dashnav.ts +++ b/public/app/features/dashboard/dashnav/dashnav.ts @@ -137,8 +137,8 @@ export class DashNavCtrl { $scope.deleteDashboard = function() { $scope.appEvent('confirm-modal', { - title: 'Delete dashboard', - text: 'Do you want to delete dashboard?', + title: 'Delete', + text: 'Do you want to delete this dashboard?', text2: $scope.dashboard.title, icon: 'fa-trash', yesText: 'Delete', diff --git a/public/app/features/plugins/import_list/import_list.html b/public/app/features/plugins/import_list/import_list.html index d6c1bb914ce..f9dc4ff28d0 100644 --- a/public/app/features/plugins/import_list/import_list.html +++ b/public/app/features/plugins/import_list/import_list.html @@ -21,13 +21,13 @@ diff --git a/public/app/features/plugins/import_list/import_list.ts b/public/app/features/plugins/import_list/import_list.ts index 004fde69bd1..19f847a58d0 100644 --- a/public/app/features/plugins/import_list/import_list.ts +++ b/public/app/features/plugins/import_list/import_list.ts @@ -34,7 +34,7 @@ export class DashImportListCtrl { }); } - this.backendSrv.post(`/api/plugins/dashboards/install`, installCmd).then(res => { + this.backendSrv.post(`/api/plugins/dashboards/import`, installCmd).then(res => { this.$rootScope.appEvent('alert-success', ['Dashboard Installed', dash.title]); _.extend(dash, res); }); diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index ff2f981e58b..3305bfd67af 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -74,7 +74,7 @@
- +
diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json new file mode 100644 index 00000000000..b9f2db18927 --- /dev/null +++ b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json @@ -0,0 +1,176 @@ +{ + "__inputs": { + "graphite": { + "type": "datasource", + "pluginId": "graphite", + "description": "Graphite datasource" + } + }, + + "revision": "1.0", + "title": "Graphite Carbon Metrics", + "tags": ["graphite", "carbon"], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapsable": true, + "collapse": false, + "editable": true, + "height": "350px", + "notice": false, + "panels": [ + { + "aliasColors": {}, + "annotate": { + "enable": false + }, + "bars": false, + "datasource": "$__graphite", + "editable": true, + "fill": 0, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "max": null, + "min": 0, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "loadingEditor": false, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "resolution": 100, + "scale": 1, + "seriesOverrides": [ + { + "alias": "Points Per Update", + "yaxis": 2 + }, + { + "alias": "CPU", + "yaxis": 2 + } + ], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "refId": "A", + "target": "alias(sumSeries(carbon.agents.*.updateOperations),\"Updates\") " + }, + { + "refId": "B", + "target": "alias(sumSeries(carbon.agents.*.metricsReceived),'Metrics Received')" + }, + { + "refId": "C", + "target": "alias(sumSeries(carbon.agents.*.committedPoints),'Committed Points')" + }, + { + "refId": "D", + "target": "alias(sumSeries(carbon.agents.*.pointsPerUpdate),'Points Per Update')" + }, + { + "refId": "E", + "target": "alias(averageSeries(carbon.agents.*.cpuUsage),'CPU')" + }, + { + "refId": "F", + "target": "alias(sumSeries(carbon.agents.*.creates),'Creates')" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Graphite Carbon Metrics", + "tooltip": { + "query_as_alias": true, + "shared": false, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "zerofill": true + } + ], + "title": "Row1" + } + ], + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "collapse": false, + "enable": true, + "notice": false, + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "templating": { + "enable": false, + "list": [] + }, + "annotations": { + "enable": false, + "list": [] + }, + "refresh": false, + "schemaVersion": 8, + "version": 2, + "links": [] +} diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json deleted file mode 100644 index 3cdfb0049c9..00000000000 --- a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "__inputs": { - "graphite": { - "type": "datasource", - "pluginId": "graphite", - "description": "Graphite datasource" - } - }, - - "title": "Carbon Cache Stats", - "version": 1, - "rows": [ - { - "panels": [ - { - "type": "graph", - "datasource": "$__graphite" - } - ] - } - ] -} diff --git a/public/app/plugins/datasource/graphite/plugin.json b/public/app/plugins/datasource/graphite/plugin.json index f7715f9c5b9..a1c35094701 100644 --- a/public/app/plugins/datasource/graphite/plugin.json +++ b/public/app/plugins/datasource/graphite/plugin.json @@ -4,7 +4,7 @@ "id": "graphite", "includes": [ - {"type": "dashboard", "name": "Carbon Cache Stats", "path": "dashboards/carbon_stats.json"} + {"type": "dashboard", "name": "Graphite Carbon Metrics", "path": "dashboards/carbon_metrics.json"} ], "metrics": true, diff --git a/tests/test-app/dashboards/connections.json b/tests/test-app/dashboards/connections.json index feb90cae71d..2f5102fba3e 100644 --- a/tests/test-app/dashboards/connections.json +++ b/tests/test-app/dashboards/connections.json @@ -10,6 +10,10 @@ "title": "Nginx Connections", "revision": "1.5", "schemaVersion": 11, + "tags": ["tag1", "tag2"], + "number_array": [1,2,3,10.33], + "boolean_true": true, + "boolean_false": false, "rows": [ { diff --git a/tests/test-app/dashboards/connections_result.json b/tests/test-app/dashboards/connections_result.json new file mode 100644 index 00000000000..1c662f6c269 --- /dev/null +++ b/tests/test-app/dashboards/connections_result.json @@ -0,0 +1,20 @@ +{ + "revision": "1.5", + "tags": ["tag1", "tag2"], + "boolean_false": false, + "boolean_true": true, + "number_array": [1,2,3,10.33], + "rows": [ + { + "panels": [ + { + "datasource": "graphite", + "type": "graph" + } + ] + } + ], + "schemaVersion": 11, + "title": "Nginx Connections", + "version": 0 +} From d575a5ce1230c3ed51cc148aa7e962a706219b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 12 Mar 2016 10:40:55 +0100 Subject: [PATCH 10/33] feat(plugins): added prometheus dashboard to prometheus data source, #4298 --- pkg/plugins/dashboard_importer.go | 33 +- pkg/plugins/dashboard_importer_test.go | 9 +- .../graphite/dashboards/carbon_metrics.json | 12 +- .../dashboards/prometheus_stats.json | 577 ++++++++++++++++++ .../plugins/datasource/prometheus/plugin.json | 4 + tests/test-app/dashboards/connections.json | 12 +- 6 files changed, 615 insertions(+), 32 deletions(-) create mode 100644 public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index b5dc286f6d1..834bfabd048 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -7,7 +7,6 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/log" m "github.com/grafana/grafana/pkg/models" ) @@ -95,11 +94,10 @@ type DashTemplateEvaluator struct { varRegex *regexp.Regexp } -func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson.Json) *ImportDashboardInput { - inputType := varDef.Get("type").MustString() +func (this *DashTemplateEvaluator) findInput(varName string, varType string) *ImportDashboardInput { for _, input := range this.inputs { - if inputType == input.Type && (input.Name == varName || input.Name == "*") { + if varType == input.Type && (input.Name == varName || input.Name == "*") { return &input } } @@ -110,21 +108,20 @@ func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson. func (this *DashTemplateEvaluator) Eval() (*simplejson.Json, error) { this.result = simplejson.New() this.variables = make(map[string]string) - this.varRegex, _ = regexp.Compile("\\$__(\\w+)") + this.varRegex, _ = regexp.Compile(`(\$\{\w+\})`) // check that we have all inputs we need - if inputDefs := this.template.Get("__inputs"); inputDefs != nil { - for varName, value := range inputDefs.MustMap() { - input := this.findInput(varName, simplejson.NewFromAny(value)) + for _, inputDef := range this.template.Get("__inputs").MustArray() { + inputDefJson := simplejson.NewFromAny(inputDef) + inputName := inputDefJson.Get("name").MustString() + inputType := inputDefJson.Get("type").MustString() + input := this.findInput(inputName, inputType) - if input == nil { - return nil, &DashboardInputMissingError{VariableName: varName} - } - - this.variables["$__"+varName] = input.Value + if input == nil { + return nil, &DashboardInputMissingError{VariableName: inputName} } - } else { - log.Info("Import: dashboard has no __import section") + + this.variables["${"+inputName+"}"] = input.Value } return simplejson.NewFromAny(this.evalObject(this.template)), nil @@ -137,7 +134,11 @@ func (this *DashTemplateEvaluator) evalValue(source *simplejson.Json) interface{ switch v := sourceValue.(type) { case string: interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string { - return this.variables[match] + if replacement, exists := this.variables[match]; exists { + return replacement + } else { + return match + } }) return interpolated case bool: diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go index 9b5605277d4..d2897fad1cd 100644 --- a/pkg/plugins/dashboard_importer_test.go +++ b/pkg/plugins/dashboard_importer_test.go @@ -59,13 +59,14 @@ func TestDashboardImport(t *testing.T) { Convey("When evaling dashboard template", t, func() { template, _ := simplejson.NewJson([]byte(`{ - "__inputs": { - "graphite": { + "__inputs": [ + { + "name": "DS_NAME", "type": "datasource" } - }, + ], "test": { - "prop": "$__graphite" + "prop": "${DS_NAME}" } }`)) diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json index b9f2db18927..845fc1930bd 100644 --- a/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json +++ b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json @@ -1,11 +1,11 @@ { - "__inputs": { - "graphite": { + "__inputs": [ + { + "name": "DS_NAME", "type": "datasource", - "pluginId": "graphite", - "description": "Graphite datasource" + "pluginId": "graphite" } - }, + ], "revision": "1.0", "title": "Graphite Carbon Metrics", @@ -29,7 +29,7 @@ "enable": false }, "bars": false, - "datasource": "$__graphite", + "datasource": "${DS_NAME}", "editable": true, "fill": 0, "grid": { diff --git a/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json new file mode 100644 index 00000000000..e008317a96e --- /dev/null +++ b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json @@ -0,0 +1,577 @@ +{ + "__inputs": [ + { + "name": "DS_NAME", + "type": "datasource", + "pluginId": "prometheus" + } + ], + + "revision": "1.0", + "title": "Prometheus Stats", + "tags": ["prometheus"], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": true, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": 178, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "${DS_NAME}", + "decimals": 1, + "editable": true, + "error": false, + "format": "s", + "id": 5, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "expr": "(time() - process_start_time_seconds{job=\"prometheus\"})", + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "", + "title": "Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "format": "none", + "id": 6, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "targets": [ + { + "expr": "prometheus_local_storage_memory_series", + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "0,1,5", + "title": "Local Storage Memory Series", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "format": "none", + "id": 7, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "targets": [ + { + "expr": "prometheus_local_storage_indexing_queue_length", + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "0,500,4000", + "title": "Interal Storage Queue Length", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [ + { + "op": "=", + "text": "Empty", + "value": "0" + } + ], + "valueName": "current" + }, + { + "content": "\"Prometheus\nPrometheus\n\n

You're using Prometheus, an open-source systems monitoring and alerting toolkit originally built at SoundCloud. For more information, check out the Grafana and Prometheus projects.

", + "editable": true, + "error": false, + "id": 9, + "links": [], + "mode": "html", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": 227, + "panels": [ + { + "aliasColors": { + "prometheus": "#C15C17", + "{instance=\"localhost:9090\",job=\"prometheus\"}": "#C15C17" + }, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_local_storage_ingested_samples_total[5m])", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "metric": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Samples ingested (rate-5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "content": "#### Samples Ingested\nThis graph displays the count of samples ingested by the Prometheus server, as measured over the last 5 minutes, per time series in the range vector. When troubleshooting an issue on IRC or Github, this is often the first stat requested by the Prometheus team. ", + "editable": true, + "error": false, + "id": 8, + "links": [], + "mode": "markdown", + "span": 2.995914043583536, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": { + "prometheus": "#F9BA8F", + "{instance=\"localhost:9090\",interval=\"5s\",job=\"prometheus\"}": "#F9BA8F" + }, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_target_interval_length_seconds_count[5m])", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Target Scrapes (last 5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_target_interval_length_seconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}} ({{interval}})", + "metric": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Scrape Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "content": "#### Scrapes\nPrometheus scrapes metrics from instrumented jobs, either directly or via an intermediary push gateway for short-lived jobs. Target scrapes will show how frequently targets are scraped, as measured over the last 5 minutes, per time series in the range vector. Scrape Duration will show how long the scrapes are taking, with percentiles available as series. ", + "editable": true, + "error": false, + "id": 11, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_NAME}", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 12, + "leftYAxisLabel": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_evaluator_duration_milliseconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Rule Eval Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "percentunit", + "short" + ] + }, + { + "content": "#### Rule Evaluation Duration\nThis graph panel plots the duration for all evaluations to execute. The 50th percentile, 90th percentile and 99th percentile are shown as three separate series to help identify outliers that may be skewing the data.", + "editable": true, + "error": false, + "id": 15, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "schemaVersion": 7, + "links": [ + { + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Grafana Docs", + "tooltip": "", + "type": "link", + "url": "http://www.grafana.org/docs" + }, + { + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Prometheus Docs", + "type": "link", + "url": "http://prometheus.io/docs/introduction/overview/" + } + ] +} diff --git a/public/app/plugins/datasource/prometheus/plugin.json b/public/app/plugins/datasource/prometheus/plugin.json index 66dd9145e6a..2ff198d5129 100644 --- a/public/app/plugins/datasource/prometheus/plugin.json +++ b/public/app/plugins/datasource/prometheus/plugin.json @@ -3,6 +3,10 @@ "name": "Prometheus", "id": "prometheus", + "includes": [ + {"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"} + ], + "metrics": true, "annotations": true } diff --git a/tests/test-app/dashboards/connections.json b/tests/test-app/dashboards/connections.json index 2f5102fba3e..ee5e40140b3 100644 --- a/tests/test-app/dashboards/connections.json +++ b/tests/test-app/dashboards/connections.json @@ -1,11 +1,11 @@ { - "__inputs": { - "graphite": { + "__inputs": [ + { + "name": "DS_NAME", "type": "datasource", - "pluginId": "graphite", - "description": "Graphite datasource" + "pluginId": "graphite" } - }, + ], "title": "Nginx Connections", "revision": "1.5", @@ -20,7 +20,7 @@ "panels": [ { "type": "graph", - "datasource": "$__graphite" + "datasource": "${DS_NAME}" } ] } From 4a3c19c666e7d627fdf8ab7359f9c4d7bca33953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 12 Mar 2016 10:49:30 +0100 Subject: [PATCH 11/33] plugins(): dashboards, changed wording installed to imported when showing imported version in dashboard list --- public/app/features/plugins/import_list/import_list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/plugins/import_list/import_list.html b/public/app/features/plugins/import_list/import_list.html index f9dc4ff28d0..acb6654d520 100644 --- a/public/app/features/plugins/import_list/import_list.html +++ b/public/app/features/plugins/import_list/import_list.html @@ -17,7 +17,7 @@ v{{dash.revision}} - Installed v{{dash.installedRevision}} + Imported v{{dash.installedRevision}}
-
-
- -
-
- -
-
-
-
- -
+
+ + +
+
+
+ +
+
diff --git a/public/app/features/plugins/plugin_list_ctrl.ts b/public/app/features/plugins/plugin_list_ctrl.ts index 2693a4d8755..9e9b679c6c1 100644 --- a/public/app/features/plugins/plugin_list_ctrl.ts +++ b/public/app/features/plugins/plugin_list_ctrl.ts @@ -4,11 +4,28 @@ import angular from 'angular'; export class PluginListCtrl { plugins: any[]; + tabIndex: number; /** @ngInject */ - constructor(private backendSrv: any) { + constructor(private backendSrv: any, $location) { + this.tabIndex = 0; - this.backendSrv.get('api/plugins', {embedded: 0}).then(plugins => { + var pluginType = $location.search().type || 'panel'; + switch (pluginType) { + case "datasource": { + this.tabIndex = 1; + break; + } + case "app": { + this.tabIndex = 2; + break; + } + case "panel": + default: + this.tabIndex = 0; + } + + this.backendSrv.get('api/plugins', {embedded: 0, type: pluginType}).then(plugins => { this.plugins = plugins; }); } From fc6ad2059a68c302cc6046d89551841fa3b416a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 14 Mar 2016 10:03:18 +0100 Subject: [PATCH 16/33] docs(): updated doc version --- docs/Makefile | 2 +- docs/VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index f24a63065b3..b1a72adc3f8 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -44,7 +44,7 @@ docs-test: docs-build $(DOCKER_RUN_DOCS) "$(DOCKER_DOCS_IMAGE)" ./test.sh docs-build: - git fetch https://github.com/grafana/grafana.git docs-2.5 && git diff --name-status FETCH_HEAD...HEAD -- . > changed-files + git fetch https://github.com/grafana/grafana.git docs-2.6 && git diff --name-status FETCH_HEAD...HEAD -- . > changed-files echo "$(GIT_BRANCH)" > GIT_BRANCH echo "$(GITCOMMIT)" > GITCOMMIT docker build -t "$(DOCKER_DOCS_IMAGE)" . diff --git a/docs/VERSION b/docs/VERSION index e70b4523ae7..4a36342fcab 100644 --- a/docs/VERSION +++ b/docs/VERSION @@ -1 +1 @@ -2.6.0 +3.0.0 From 4aba3bc62bbfcc87419b4e31599b38bb235cbe26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 14 Mar 2016 10:18:43 +0100 Subject: [PATCH 17/33] fix(opentsdb): fixed templating issue for OpenTSDB, fixes #4312, fixes #4311 --- public/app/features/templating/templateSrv.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/public/app/features/templating/templateSrv.js b/public/app/features/templating/templateSrv.js index 3527c386220..ece69302196 100644 --- a/public/app/features/templating/templateSrv.js +++ b/public/app/features/templating/templateSrv.js @@ -43,6 +43,9 @@ function (angular, _) { } this.formatValue = function(value, format, variable) { + // for some scopedVars there is no variable + variable = variable || {}; + if (typeof format === 'function') { return format(value, variable, this.formatValue); } @@ -126,9 +129,6 @@ function (angular, _) { return target.replace(this._regex, function(match, g1, g2) { variable = self._index[g1 || g2]; - if (!variable) { - return match; - } if (scopedVars) { value = scopedVars[g1 || g2]; @@ -137,6 +137,10 @@ function (angular, _) { } } + if (!variable) { + return match; + } + systemValue = self._grafanaVariables[variable.current.value]; if (systemValue) { return self.formatValue(systemValue, format, variable); From f77bd59e1da4300c757284c293808ebb4b97c677 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 14 Mar 2016 11:33:38 +0100 Subject: [PATCH 18/33] fix(datasource): fixes testdatasource bug --- public/app/features/plugins/partials/ds_edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index 3305bfd67af..8822000df91 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -64,7 +64,7 @@
- Cancel From 953a07252afdfe6f7dbe2de7a69b1ac27ab78268 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 14 Mar 2016 11:43:35 +0100 Subject: [PATCH 19/33] Revert "fix(datasource): fixes testdatasource bug" This reverts commit f77bd59e1da4300c757284c293808ebb4b97c677. --- public/app/features/plugins/partials/ds_edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/plugins/partials/ds_edit.html b/public/app/features/plugins/partials/ds_edit.html index 8822000df91..3305bfd67af 100644 --- a/public/app/features/plugins/partials/ds_edit.html +++ b/public/app/features/plugins/partials/ds_edit.html @@ -64,7 +64,7 @@
- Cancel From ca5a34ad1ee4a8004135c49e31e466aff91e9521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 14 Mar 2016 12:00:56 +0100 Subject: [PATCH 20/33] fix(datasource): filter out built in data sources from data source type dropdown --- pkg/api/plugins.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index 195dd9483b8..2ee77ff0a92 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -48,6 +48,13 @@ func GetPluginList(c *middleware.Context) Response { continue } + // filter out built in data sources + if ds, exists := plugins.DataSources[pluginDef.Id]; exists { + if ds.BuiltIn { + continue + } + } + result = append(result, listItem) } From 8f97e8d5edb0fa02e9207800c70d5d166ecd134a Mon Sep 17 00:00:00 2001 From: Sean Kenny Date: Mon, 14 Mar 2016 19:40:23 +0000 Subject: [PATCH 21/33] Fix minor typo in tooltip --- .../plugins/datasource/elasticsearch/partials/bucket_agg.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html index 5c1b538cf9a..3ddbfed3f80 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html +++ b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html @@ -66,7 +66,7 @@
  • - +
  • From e905c2c6b589dbbef9ee3e9a4ed67a8550ad9112 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 14 Mar 2016 17:16:10 +0100 Subject: [PATCH 22/33] feat(plugin.json): remove staticRoot field --- pkg/plugins/frontend_plugin.go | 15 +++++++++------ pkg/plugins/models.go | 18 ++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/pkg/plugins/frontend_plugin.go b/pkg/plugins/frontend_plugin.go index aab3f851f60..cd7f9703aae 100644 --- a/pkg/plugins/frontend_plugin.go +++ b/pkg/plugins/frontend_plugin.go @@ -3,9 +3,9 @@ package plugins import ( "net/url" "path" - "path/filepath" "strings" + "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) @@ -14,10 +14,9 @@ type FrontendPluginBase struct { } func (fp *FrontendPluginBase) initFrontendPlugin() { - if fp.StaticRoot != "" { - fp.StaticRootAbs = filepath.Join(fp.PluginDir, fp.StaticRoot) + if isInternalPlugin(fp.PluginDir) { StaticRoutes = append(StaticRoutes, &PluginStaticRoute{ - Directory: fp.StaticRootAbs, + Directory: fp.PluginDir, PluginId: fp.Id, }) } @@ -33,7 +32,7 @@ func (fp *FrontendPluginBase) initFrontendPlugin() { } func (fp *FrontendPluginBase) setPathsBasedOnApp(app *AppPlugin) { - appSubPath := strings.Replace(fp.PluginDir, app.StaticRootAbs, "", 1) + appSubPath := strings.Replace(fp.PluginDir, app.PluginDir, "", 1) fp.IncludedInAppId = app.Id fp.BaseUrl = app.BaseUrl fp.Module = util.JoinUrlFragments("plugins/"+app.Id, appSubPath) + "/module" @@ -41,7 +40,7 @@ func (fp *FrontendPluginBase) setPathsBasedOnApp(app *AppPlugin) { func (fp *FrontendPluginBase) handleModuleDefaults() { - if fp.StaticRoot != "" { + if isInternalPlugin(fp.PluginDir) { fp.Module = path.Join("plugins", fp.Id, "module") fp.BaseUrl = path.Join("public/plugins", fp.Id) return @@ -51,6 +50,10 @@ func (fp *FrontendPluginBase) handleModuleDefaults() { fp.BaseUrl = path.Join("public/app/plugins", fp.Type, fp.Id) } +func isInternalPlugin(pluginDir string) bool { + return !strings.Contains(pluginDir, setting.StaticRootPath) +} + func evalRelativePluginUrlPath(pathStr string, baseUrl string) string { if pathStr == "" { return "" diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index 07c3d321ec7..8443e91931d 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -30,16 +30,14 @@ type PluginLoader interface { } type PluginBase struct { - Type string `json:"type"` - Name string `json:"name"` - Id string `json:"id"` - Info PluginInfo `json:"info"` - Dependencies PluginDependencies `json:"dependencies"` - Includes []*PluginInclude `json:"includes"` - Module string `json:"module"` - BaseUrl string `json:"baseUrl"` - StaticRoot string `json:"staticRoot"` - StaticRootAbs string `json:"-"` + Type string `json:"type"` + Name string `json:"name"` + Id string `json:"id"` + Info PluginInfo `json:"info"` + Dependencies PluginDependencies `json:"dependencies"` + Includes []*PluginInclude `json:"includes"` + Module string `json:"module"` + BaseUrl string `json:"baseUrl"` IncludedInAppId string `json:"-"` PluginDir string `json:"-"` From 82eb32a71ecc1cc2f20d2cf039243f143a67805a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 15 Mar 2016 09:15:24 +0100 Subject: [PATCH 23/33] ux(): initial pass at new card / list design, #4364 --- pkg/plugins/frontend_plugin.go | 12 ++- .../plugins/partials/plugin_list.html | 55 ++++++------- .../cloudwatch/img/amazon-web-services.png | Bin 0 -> 9559 bytes .../plugins/datasource/cloudwatch/plugin.json | 13 +++- .../datasource/elasticsearch/plugin.json | 2 +- .../plugins/datasource/graphite/plugin.json | 9 ++- .../datasource/influxdb/img/influxdb_logo.svg | 15 ++++ .../plugins/datasource/influxdb/plugin.json | 13 +++- .../datasource/opentsdb/img/opentsdb_logo.png | Bin 0 -> 11644 bytes .../plugins/datasource/opentsdb/plugin.json | 13 +++- .../prometheus/img/prometheus_logo.svg | 19 +++++ .../plugins/datasource/prometheus/plugin.json | 13 +++- public/app/plugins/panel/dashlist/plugin.json | 9 ++- public/app/plugins/panel/graph/plugin.json | 9 ++- .../app/plugins/panel/singlestat/plugin.json | 9 ++- public/app/plugins/panel/table/plugin.json | 9 ++- public/app/plugins/panel/text/plugin.json | 9 ++- public/img/plugin-default-logo_dark.svg | 26 +++++++ public/img/plugin-default-logo_light.svg | 24 ++++++ public/sass/_grafana.scss | 1 + public/sass/_variables.dark.scss | 13 +++- public/sass/_variables.light.scss | 6 ++ public/sass/_variables.scss | 2 +- public/sass/base/_fonts.scss | 7 ++ public/sass/components/_cards.scss | 73 ++++++++++++++++++ 25 files changed, 311 insertions(+), 50 deletions(-) create mode 100644 public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png create mode 100644 public/app/plugins/datasource/influxdb/img/influxdb_logo.svg create mode 100644 public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png create mode 100644 public/app/plugins/datasource/prometheus/img/prometheus_logo.svg create mode 100644 public/img/plugin-default-logo_dark.svg create mode 100644 public/img/plugin-default-logo_light.svg create mode 100644 public/sass/components/_cards.scss diff --git a/pkg/plugins/frontend_plugin.go b/pkg/plugins/frontend_plugin.go index aab3f851f60..5e1b4556a16 100644 --- a/pkg/plugins/frontend_plugin.go +++ b/pkg/plugins/frontend_plugin.go @@ -24,14 +24,22 @@ func (fp *FrontendPluginBase) initFrontendPlugin() { fp.handleModuleDefaults() - fp.Info.Logos.Small = evalRelativePluginUrlPath(fp.Info.Logos.Small, fp.BaseUrl) - fp.Info.Logos.Large = evalRelativePluginUrlPath(fp.Info.Logos.Large, fp.BaseUrl) + fp.Info.Logos.Small = getPluginLogoUrl(fp.Info.Logos.Small, fp.BaseUrl) + fp.Info.Logos.Large = getPluginLogoUrl(fp.Info.Logos.Large, fp.BaseUrl) for i := 0; i < len(fp.Info.Screenshots); i++ { fp.Info.Screenshots[i].Path = evalRelativePluginUrlPath(fp.Info.Screenshots[i].Path, fp.BaseUrl) } } +func getPluginLogoUrl(path, baseUrl string) string { + if path == "" { + return "public/img/plugin-default-logo_dark.svg" + } + + return evalRelativePluginUrlPath(path, baseUrl) +} + func (fp *FrontendPluginBase) setPathsBasedOnApp(app *AppPlugin) { appSubPath := strings.Replace(fp.PluginDir, app.StaticRootAbs, "", 1) fp.IncludedInAppId = app.Id diff --git a/public/app/features/plugins/partials/plugin_list.html b/public/app/features/plugins/partials/plugin_list.html index 5c3d38b3459..e11860235e5 100644 --- a/public/app/features/plugins/partials/plugin_list.html +++ b/public/app/features/plugins/partials/plugin_list.html @@ -26,37 +26,26 @@
    - - - - - - - - - - - - - - - - - -
    NameType
    - - {{plugin.name}} - - - {{plugin.type}} - - Enabled - Pinned - - - - Edit - -
    -
    +
    +
      +
    1. + +
      + + {{plugin.type}} +
      +
      +
      + +
      +
      +
      {{plugin.name}}
      +
      By {{plugin.info.author.name}}
      +
      +
      +
      +
    2. +
    +
    +
    diff --git a/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png b/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png new file mode 100644 index 0000000000000000000000000000000000000000..f11f40347510903c178610d44d261ef530db2dc5 GIT binary patch literal 9559 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 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/cloudwatch/plugin.json b/public/app/plugins/datasource/cloudwatch/plugin.json index 49c5341bd21..eb2f97335da 100644 --- a/public/app/plugins/datasource/cloudwatch/plugin.json +++ b/public/app/plugins/datasource/cloudwatch/plugin.json @@ -4,5 +4,16 @@ "id": "cloudwatch", "metrics": true, - "annotations": true + "annotations": true, + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + }, + "logos": { + "small": "img/amazon-web-services.png", + "large": "img/amazon-web-services.png" + } + } } diff --git a/public/app/plugins/datasource/elasticsearch/plugin.json b/public/app/plugins/datasource/elasticsearch/plugin.json index 3cd345e5cdf..d4b07ac8e00 100644 --- a/public/app/plugins/datasource/elasticsearch/plugin.json +++ b/public/app/plugins/datasource/elasticsearch/plugin.json @@ -6,7 +6,7 @@ "info": { "description": "Elasticsearch Data Source for Grafana", "author": { - "name": "Grafana Core", + "name": "Grafana Project", "url": "http://grafana.org" }, "keywords": ["elasticsearch"], diff --git a/public/app/plugins/datasource/graphite/plugin.json b/public/app/plugins/datasource/graphite/plugin.json index a1c35094701..a561a99372b 100644 --- a/public/app/plugins/datasource/graphite/plugin.json +++ b/public/app/plugins/datasource/graphite/plugin.json @@ -8,5 +8,12 @@ ], "metrics": true, - "annotations": true + "annotations": true, + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/app/plugins/datasource/influxdb/img/influxdb_logo.svg b/public/app/plugins/datasource/influxdb/img/influxdb_logo.svg new file mode 100644 index 00000000000..6fad144f8c7 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/img/influxdb_logo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/app/plugins/datasource/influxdb/plugin.json b/public/app/plugins/datasource/influxdb/plugin.json index dd60a16b715..605ce168831 100644 --- a/public/app/plugins/datasource/influxdb/plugin.json +++ b/public/app/plugins/datasource/influxdb/plugin.json @@ -5,5 +5,16 @@ "defaultMatchFormat": "regex values", "metrics": true, - "annotations": true + "annotations": true, + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + }, + "logos": { + "small": "img/influxdb_logo.svg", + "large": "img/influxdb_logo.svg" + } + } } diff --git a/public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png b/public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..519d56a476c4c24558ca0bca4b50f9adfa948adc GIT binary patch literal 11644 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 Pqyewx)#NH;NP literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/opentsdb/plugin.json b/public/app/plugins/datasource/opentsdb/plugin.json index 333e9d07536..02ba02e6e89 100644 --- a/public/app/plugins/datasource/opentsdb/plugin.json +++ b/public/app/plugins/datasource/opentsdb/plugin.json @@ -5,5 +5,16 @@ "metrics": true, "defaultMatchFormat": "pipe", - "annotations": true + "annotations": true, + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + }, + "logos": { + "small": "img/opentsdb_logo.png", + "large": "img/opentsdb_logo.png" + } + } } diff --git a/public/app/plugins/datasource/prometheus/img/prometheus_logo.svg b/public/app/plugins/datasource/prometheus/img/prometheus_logo.svg new file mode 100644 index 00000000000..29005ec3860 --- /dev/null +++ b/public/app/plugins/datasource/prometheus/img/prometheus_logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/public/app/plugins/datasource/prometheus/plugin.json b/public/app/plugins/datasource/prometheus/plugin.json index 2ff198d5129..f39f8691661 100644 --- a/public/app/plugins/datasource/prometheus/plugin.json +++ b/public/app/plugins/datasource/prometheus/plugin.json @@ -8,5 +8,16 @@ ], "metrics": true, - "annotations": true + "annotations": true, + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + }, + "logos": { + "small": "img/prometheus_logo.svg", + "large": "img/prometheus_logo.svg" + } + } } diff --git a/public/app/plugins/panel/dashlist/plugin.json b/public/app/plugins/panel/dashlist/plugin.json index 1f1266d8444..9cac424ac68 100644 --- a/public/app/plugins/panel/dashlist/plugin.json +++ b/public/app/plugins/panel/dashlist/plugin.json @@ -1,5 +1,12 @@ { "type": "panel", "name": "Dashboard list", - "id": "dashlist" + "id": "dashlist", + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/app/plugins/panel/graph/plugin.json b/public/app/plugins/panel/graph/plugin.json index f603e5e4b06..baa9fe12a39 100644 --- a/public/app/plugins/panel/graph/plugin.json +++ b/public/app/plugins/panel/graph/plugin.json @@ -1,5 +1,12 @@ { "type": "panel", "name": "Graph", - "id": "graph" + "id": "graph", + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/app/plugins/panel/singlestat/plugin.json b/public/app/plugins/panel/singlestat/plugin.json index 8372e4b2c2d..ea9ae32853a 100644 --- a/public/app/plugins/panel/singlestat/plugin.json +++ b/public/app/plugins/panel/singlestat/plugin.json @@ -1,5 +1,12 @@ { "type": "panel", "name": "Singlestat", - "id": "singlestat" + "id": "singlestat", + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/app/plugins/panel/table/plugin.json b/public/app/plugins/panel/table/plugin.json index 7f8c0bb23cf..e25efdfbe36 100644 --- a/public/app/plugins/panel/table/plugin.json +++ b/public/app/plugins/panel/table/plugin.json @@ -1,5 +1,12 @@ { "type": "panel", "name": "Table", - "id": "table" + "id": "table", + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/app/plugins/panel/text/plugin.json b/public/app/plugins/panel/text/plugin.json index 4cf046cec36..485f42942f2 100644 --- a/public/app/plugins/panel/text/plugin.json +++ b/public/app/plugins/panel/text/plugin.json @@ -1,5 +1,12 @@ { "type": "panel", "name": "Text", - "id": "text" + "id": "text", + + "info": { + "author": { + "name": "Grafana Project", + "url": "http://grafana.org" + } + } } diff --git a/public/img/plugin-default-logo_dark.svg b/public/img/plugin-default-logo_dark.svg new file mode 100644 index 00000000000..d665aa30b07 --- /dev/null +++ b/public/img/plugin-default-logo_dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/img/plugin-default-logo_light.svg b/public/img/plugin-default-logo_light.svg new file mode 100644 index 00000000000..4573494ff16 --- /dev/null +++ b/public/img/plugin-default-logo_light.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 42956f3c3fa..f8973c65dc7 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -30,6 +30,7 @@ @import "layout/page"; // COMPONENTS +@import "components/cards"; @import "components/buttons"; @import "components/navs"; @import "components/tabs"; diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 8823b336d83..8efd9f7e55d 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -67,9 +67,9 @@ $link-hover-color: $white; // Typography // ------------------------- -$headings-color: darken($white,11%); -$abbr-border-color: $gray-3 !default; -$text-muted: darken($link-color,30%); +$headings-color: darken($white,11%); +$abbr-border-color: $gray-3 !default; +$text-muted: darken($link-color,30%); $blockquote-small-color: $gray-3 !default; $blockquote-border-color: $gray-4 !default; @@ -252,3 +252,10 @@ $popover-help-color: $text-color; // images $checkboxImageUrl: '../img/checkbox.png'; + +// cards +$card-background: linear-gradient(135deg, #2f2f2f, #262626); +$card-background-hover: linear-gradient(135deg, #343434, #262626); +$card-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, .1), 1px 1px 0 0 rgba(0, 0, 0, .3); + + diff --git a/public/sass/_variables.light.scss b/public/sass/_variables.light.scss index af66e2c2389..279e284b0be 100644 --- a/public/sass/_variables.light.scss +++ b/public/sass/_variables.light.scss @@ -279,3 +279,9 @@ $popover-help-color: $gray-6; // images $checkboxImageUrl: '../img/checkbox_white.png'; + +// cards +$card-background: linear-gradient(135deg, $gray-5, $gray-6); +$card-background-hover: linear-gradient(135deg, $gray-6, $gray-7); +$card-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, .1), 1px 1px 0 0 rgba(0, 0, 0, .1); + diff --git a/public/sass/_variables.scss b/public/sass/_variables.scss index 4f1002bdc67..9f96591a4b9 100644 --- a/public/sass/_variables.scss +++ b/public/sass/_variables.scss @@ -4,7 +4,7 @@ // // Quickly modify global styling by enabling or disabling optional features. -$enable-flex: false !default; +$enable-flex: true !default; $enable-rounded: true !default; $enable-shadows: false !default; $enable-gradients: false !default; diff --git a/public/sass/base/_fonts.scss b/public/sass/base/_fonts.scss index f7d172a523f..e442cbdce6c 100644 --- a/public/sass/base/_fonts.scss +++ b/public/sass/base/_fonts.scss @@ -176,3 +176,10 @@ content: "\e903"; } +.icon-gf-app:before { + content: "\e902"; +} +.icon-gf-datasource:before { + content: "\e607"; +} + diff --git a/public/sass/components/_cards.scss b/public/sass/components/_cards.scss new file mode 100644 index 00000000000..12d3b0166ff --- /dev/null +++ b/public/sass/components/_cards.scss @@ -0,0 +1,73 @@ + + +.card-section { + margin-bottom: $spacer*2; +} + +.card-list { + display: flex; + flex-direction: row; + flex-wrap: wrap; + list-style-type: none; +} + +.card-item-wrapper { + width: 100%; + padding: 0 1.5rem 1.5rem 0rem; +} + +.card-item { + display: block; + height: 100%; + min-height: 12rem; + background: $card-background; + box-shadow: $card-shadow; + padding: 1rem; + border-radius: 4px; + + &:hover { + background: $card-background-hover; + } +} + +.card-item-figure { + margin: 0 $spacer $spacer 0; + img { + width: 6rem; + } +} + +.card-item-body { + display: flex; +} + +.card-item-details { +} + +.card-item-header { + color: $text-color-weak; + margin-bottom: $spacer; +} + +.card-item-name { + color: $headings-color; + font-size: $font-size-h3; +} + +.card-item-sub-name { + color: $text-color-weak; +} + +@include media-breakpoint-up(md) { + .card-item-wrapper { + width: 50%; + } +} + +@include media-breakpoint-up(lg) { + .card-item-wrapper { + width: 33%; + } +} + + From cba7c1726f1c4a7d073b0674b3a884327822f4d5 Mon Sep 17 00:00:00 2001 From: Trent White Date: Tue, 15 Mar 2016 10:08:23 -0400 Subject: [PATCH 24/33] add graphite logo to datasource card --- .../datasource/graphite/img/graphite_logo.png | Bin 0 -> 6285 bytes .../app/plugins/datasource/graphite/plugin.json | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 public/app/plugins/datasource/graphite/img/graphite_logo.png diff --git a/public/app/plugins/datasource/graphite/img/graphite_logo.png b/public/app/plugins/datasource/graphite/img/graphite_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e70b40720c45c17b4bb571df5f73d6c3c11cdcf4 GIT binary patch literal 6285 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 Date: Tue, 15 Mar 2016 15:28:08 +0100 Subject: [PATCH 25/33] ux(): added card layout selector and list view mode, #4364 --- .../layout_selector/layout_selector.ts | 74 ++++++++++++++ public/app/core/core.ts | 2 + .../plugins/partials/plugin_list.html | 8 +- public/sass/components/_cards.scss | 96 +++++++++++++++---- 4 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 public/app/core/components/layout_selector/layout_selector.ts diff --git a/public/app/core/components/layout_selector/layout_selector.ts b/public/app/core/components/layout_selector/layout_selector.ts new file mode 100644 index 00000000000..e9d90aa1f48 --- /dev/null +++ b/public/app/core/components/layout_selector/layout_selector.ts @@ -0,0 +1,74 @@ +/// + +import config from 'app/core/config'; +import store from 'app/core/store'; +import _ from 'lodash'; +import $ from 'jquery'; +import coreModule from 'app/core/core_module'; + +var template = ` +
    + + +
    +`; + +export class LayoutSelectorCtrl { + mode: string; + + /** @ngInject **/ + constructor(private $rootScope) { + this.mode = store.get('grafana.list.layout.mode') || 'grid'; + } + + listView() { + this.mode = 'list'; + store.set('grafana.list.layout.mode', 'list'); + this.$rootScope.appEvent('layout-mode-changed', 'list'); + } + + gridView() { + this.mode = 'grid'; + store.set('grafana.list.layout.mode', 'grid'); + this.$rootScope.appEvent('layout-mode-changed', 'grid'); + } + +} + +/** @ngInject **/ +export function layoutSelector() { + return { + restrict: 'E', + controller: LayoutSelectorCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: {}, + template: template, + }; +} + +/** @ngInject **/ +export function layoutMode($rootScope) { + return { + restrict: 'A', + scope: {}, + link: function(scope, elem) { + var layout = store.get('grafana.list.layout.mode') || 'grid'; + var className = 'card-list-layout-' + layout; + elem.addClass(className); + + $rootScope.onAppEvent('layout-mode-changed', (evt, newLayout) => { + elem.removeClass(className); + className = 'card-list-layout-' + newLayout; + elem.addClass(className); + }, scope); + } + }; +} + +coreModule.directive('layoutSelector', layoutSelector); +coreModule.directive('layoutMode', layoutMode); diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 32ddee02dc7..2ab7ea01410 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -28,6 +28,7 @@ import {infoPopover} from './components/info_popover'; import {colorPicker} from './components/colorpicker'; import {navbarDirective} from './components/navbar/navbar'; import {arrayJoin} from './directives/array_join'; +import {layoutSelector} from './components/layout_selector/layout_selector'; import 'app/core/controllers/all'; import 'app/core/services/all'; import 'app/core/routes/routes'; @@ -42,5 +43,6 @@ export { navbarDirective, searchDirective, colorPicker, + layoutSelector, infoPopover }; diff --git a/public/app/features/plugins/partials/plugin_list.html b/public/app/features/plugins/partials/plugin_list.html index e11860235e5..aa86e9e6dd2 100644 --- a/public/app/features/plugins/partials/plugin_list.html +++ b/public/app/features/plugins/partials/plugin_list.html @@ -26,8 +26,10 @@
    -
    -
      +
      + + +
      1. @@ -36,7 +38,7 @@
        - +
        {{plugin.name}}
        diff --git a/public/sass/components/_cards.scss b/public/sass/components/_cards.scss index 12d3b0166ff..4e5b43f60f5 100644 --- a/public/sass/components/_cards.scss +++ b/public/sass/components/_cards.scss @@ -1,4 +1,27 @@ +.layout-selector { + text-align: right; + margin: 0 $spacer*1.5 $spacer; + position: relative; + top: -0.5rem; + button { + background: $input-label-bg; + color: $text-color-weak; + border: none; + padding: 0.5rem; + line-height: 1; + font-size: 130%; + + &:focus { + outline: none; + } + + &.active { + background-color: lighten($input-label-bg, 5%); + color: $link-color; + } + } +} .card-section { margin-bottom: $spacer*2; @@ -11,15 +34,9 @@ list-style-type: none; } -.card-item-wrapper { - width: 100%; - padding: 0 1.5rem 1.5rem 0rem; -} - .card-item { display: block; height: 100%; - min-height: 12rem; background: $card-background; box-shadow: $card-shadow; padding: 1rem; @@ -30,13 +47,6 @@ } } -.card-item-figure { - margin: 0 $spacer $spacer 0; - img { - width: 6rem; - } -} - .card-item-body { display: flex; } @@ -51,23 +61,71 @@ .card-item-name { color: $headings-color; - font-size: $font-size-h3; } .card-item-sub-name { color: $text-color-weak; } -@include media-breakpoint-up(md) { +.card-list-layout-grid { + .card-item-wrapper { - width: 50%; + width: 100%; + padding: 0 1.5rem 1.5rem 0rem; + } + + .card-item-figure { + margin: 0 $spacer $spacer 0; + img { + width: 6rem; + } + } + + .card-item-name { + font-size: $font-size-h3; + } + + @include media-breakpoint-up(md) { + .card-item-wrapper { + width: 50%; + } + } + + @include media-breakpoint-up(lg) { + .card-item-wrapper { + width: 33.333333%; + } } } -@include media-breakpoint-up(lg) { +.card-list-layout-list { + .card-item-wrapper { - width: 33%; + width: 100%; + padding: 0 0 1.5rem 0rem; + } + + .card-item-header { + float: right; + } + + .card-item-figure { + margin: 0 $spacer 0 0; + img { + width: 3.5rem; + } + } + + .card-item-name { + font-size: $font-size-h4; + } + + .card-item-sub-name { + font-size: $font-size-sm; + } + + .layout-selector { + margin-right: 0; } } - From 1abdd170d326595b4818920e4b837dfc330ad07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 15 Mar 2016 15:52:29 +0100 Subject: [PATCH 26/33] ux(): fixes to cards and sorting plugin list, #4364 --- pkg/api/dtos/plugins.go | 14 ++++++++++++++ pkg/api/plugins.go | 7 +++++-- public/sass/components/_cards.scss | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg/api/dtos/plugins.go b/pkg/api/dtos/plugins.go index 7008c939aef..88683155006 100644 --- a/pkg/api/dtos/plugins.go +++ b/pkg/api/dtos/plugins.go @@ -26,6 +26,20 @@ type PluginListItem struct { Info *plugins.PluginInfo `json:"info"` } +type PluginList []PluginListItem + +func (slice PluginList) Len() int { + return len(slice) +} + +func (slice PluginList) Less(i, j int) bool { + return slice[i].Name < slice[j].Name +} + +func (slice PluginList) Swap(i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} + type ImportDashboardCommand struct { PluginId string `json:"pluginId"` Path string `json:"path"` diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index 2ee77ff0a92..56d0d99296c 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -1,6 +1,8 @@ package api import ( + "sort" + "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/middleware" @@ -19,7 +21,7 @@ func GetPluginList(c *middleware.Context) Response { return ApiError(500, "Failed to get list of plugins", err) } - result := make([]*dtos.PluginListItem, 0) + result := make(dtos.PluginList, 0) for _, pluginDef := range plugins.Plugins { // filter out app sub plugins if embeddedFilter == "0" && pluginDef.IncludedInAppId != "" { @@ -31,7 +33,7 @@ func GetPluginList(c *middleware.Context) Response { continue } - listItem := &dtos.PluginListItem{ + listItem := dtos.PluginListItem{ Id: pluginDef.Id, Name: pluginDef.Name, Type: pluginDef.Type, @@ -58,6 +60,7 @@ func GetPluginList(c *middleware.Context) Response { result = append(result, listItem) } + sort.Sort(result) return Json(200, result) } diff --git a/public/sass/components/_cards.scss b/public/sass/components/_cards.scss index 4e5b43f60f5..8272de2fa3b 100644 --- a/public/sass/components/_cards.scss +++ b/public/sass/components/_cards.scss @@ -76,6 +76,8 @@ .card-item-figure { margin: 0 $spacer $spacer 0; + height: 6rem; + img { width: 6rem; } From 381a48f21de183e8502a77bf82434534775c4491 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Wed, 16 Mar 2016 15:41:52 +0900 Subject: [PATCH 27/33] (cloudwatch) remove duplicative attribute --- public/app/plugins/datasource/cloudwatch/datasource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index 704cbd41e72..a034134e657 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -222,7 +222,7 @@ function (angular, _, moment, dateMath, CloudWatchAnnotationQuery) { .map(function(reservations) { return _.pluck(reservations.Instances, targetAttributeName); }) - .flatten().value(); + .flatten().uniq().sortBy().value(); return transformSuggestData(attributes); }); } From 81c11ebb5364bde69376fa4440532a0683c2adc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 16 Mar 2016 10:32:11 +0100 Subject: [PATCH 28/33] fix(dashlist): fixed issue with viewing last viewed dashboards, when you had more than dashboards in last viewed than panel limit they did not show up in list --- public/app/plugins/panel/dashlist/module.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/panel/dashlist/module.ts b/public/app/plugins/panel/dashlist/module.ts index c0e34183548..7d3f9d74bd0 100644 --- a/public/app/plugins/panel/dashlist/module.ts +++ b/public/app/plugins/panel/dashlist/module.ts @@ -43,13 +43,10 @@ class DashListCtrl extends PanelCtrl { var params: any = {limit: this.panel.limit}; if (this.panel.mode === 'recently viewed') { - var dashboardIds = impressions.getDashboardOpened(); + var dashIds = _.first(impressions.getDashboardOpened(), this.panel.limit); - return this.backendSrv.search({ - dashboardIds: impressions.getDashboardOpened(), - limit: this.panel.limit - }).then(result => { - this.dashList = dashboardIds.map(orderId => { + return this.backendSrv.search({dashboardIds: dashIds, limit: this.panel.limit}).then(result => { + this.dashList = dashIds.map(orderId => { return _.find(result, dashboard => { return dashboard.id === orderId; }); From 99e068643b7d5c0b10545827afa986ec7bb0082a Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 16 Mar 2016 10:39:45 +0100 Subject: [PATCH 29/33] feat(fonts): download fonts from grafana instead of CDN Makes its possible to run grafana without internet access. The performance hit by not using a cdn is very small since most grafana instances are setup on locally. closes #4223 --- ...O5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 5740 bytes ...CpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2 | Bin 0 -> 2392 bytes ...CpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2 | Bin 0 -> 12412 bytes ...CpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2 | Bin 0 -> 9956 bytes ...CpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2 | Bin 0 -> 17520 bytes ...CpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2 | Bin 0 -> 8416 bytes ...CpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2 | Bin 0 -> 16152 bytes ...CpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2 | Bin 0 -> 5736 bytes ...oAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 16868 bytes ...B6EMdfHrEVqA1KRJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 2332 bytes ...JH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2 | Bin 0 -> 2332 bytes ...JH_bn48VBG8sNSj0LW-43aMEzIO6XUTLjad8.woff2 | Bin 0 -> 12692 bytes ...JH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2 | Bin 0 -> 9896 bytes ...JH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2 | Bin 0 -> 17608 bytes ...JH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2 | Bin 0 -> 8380 bytes ...JH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2 | Bin 0 -> 16164 bytes ...JH_bn48VBG8sNSv8zf_FOSsgRmwsS7Aa9k2w.woff2 | Bin 0 -> 5916 bytes ...TmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 9676 bytes ...Brn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2 | Bin 0 -> 15572 bytes ...OKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2 | Bin 0 -> 2332 bytes ...OKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2 | Bin 0 -> 12640 bytes ...OKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2 | Bin 0 -> 9848 bytes ...OKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2 | Bin 0 -> 17880 bytes ...OKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2 | Bin 0 -> 8528 bytes ...OKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2 | Bin 0 -> 16276 bytes ...OKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2 | Bin 0 -> 5832 bytes ...ET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 12288 bytes ...8I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2 | Bin 0 -> 11908 bytes ...8I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2 | Bin 0 -> 16164 bytes ...8I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2 | Bin 0 -> 9700 bytes ...8I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2 | Bin 0 -> 2296 bytes ...8I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2 | Bin 0 -> 7792 bytes ...8I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2 | Bin 0 -> 14968 bytes ...8I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2 | Bin 0 -> 5504 bytes ...2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2 | Bin 0 -> 8160 bytes public/sass/_grafana.scss | 1 - public/sass/base/_fonts.scss | 395 +++++++++++------- public/sass/base/_grafana_icons.scss | 185 ++++++++ public/sass/fonts.scss | 3 + public/views/index.html | 2 +- tasks/default_task.js | 1 + tasks/options/concat.js | 5 + tasks/options/sass.js | 1 + 43 files changed, 441 insertions(+), 152 deletions(-) create mode 100644 public/fonts/opensans/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2 create mode 100644 public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2 create mode 100644 public/fonts/opensans/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/fonts/opensans/LWCjsQkB6EMdfHrEVqA1KRJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSj0LW-43aMEzIO6XUTLjad8.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2 create mode 100644 public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSv8zf_FOSsgRmwsS7Aa9k2w.woff2 create mode 100644 public/fonts/opensans/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/fonts/opensans/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2 create mode 100644 public/fonts/opensans/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2 create mode 100644 public/fonts/opensans/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2 create mode 100644 public/fonts/opensans/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2 create mode 100644 public/fonts/opensans/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2 create mode 100644 public/sass/base/_grafana_icons.scss create mode 100644 public/sass/fonts.scss diff --git a/public/fonts/opensans/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2 b/public/fonts/opensans/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..bb845920dd11a428e038a3805513890f7d00a94e GIT binary patch literal 5740 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..04a108157582144268e92c4dfb4fc33636c89605 GIT binary patch literal 2392 zcmV-e38(gVPew8T0RR9100~$C5dZ)H01r$600{j60U4SA00000000000000000000 z0000Q92*QA32=*)K=HKwU-$}E^uU!>eN9)Dx;|qT2!J3BK?r68A_#msLf5sxdQ|s|(o-Y}9~9r4d})B_*>&PK zu}c1;2tunUi$00mApHWu-wn_O0E39bqnUCJUO=0d_1!K!u51Z51$jICh&1kdg>Hkm zCxbXEj|4hEf?NXVQ_W^#bDNb8xeL9R7GezU=Kg;8r%2=I#+!iVUm7h&#%|34*c<-; z#^#52pKJbN_ub9ENS73>ysuY`^m$ywIh2xg7YlGutMDv715EJ8ZZ}RZ%sY0qQZCKS z&P-2D7SBu+PFrR^m(3XCr%s+Ye(dOx!-o!zjtmc_l7rXBqWjr(5xuV~tcKd#T3Z5& zU-n6&K#-)I)J!f$Y1nd^$=pIJNzJ~sd@5-&tH!BIdAcaYSfS7^V=kvP%44wB?ZX;3 zQ1h({46%_xRC)p@`mUO{CGk|++Aqdc+DLxFySA-jv6cufvt{?Z%|%!21)gYn-cvlB z;5V>5zu~^$^c{7@3Qw}U$rB1)#nL|36!rZJ;l8NKsP|uRQe%JpOGoH(Wb1!XR&XK5 zNy(1*7R@@(FZVo)QOm1&?sl`j$f(M^Mlk5zZY~hBHvfa$%@1AGxOL6pYHf`ia}N6^ zt5oEja|<>Xq843qJ7iHj<&&NSM8)*&)Cwv2ywBS|gEDz+T-puvm-n`kcMs&{MP* zU<@Z5F4U-^PsqBfqPm(FYbGK{vkwWV!6e<7RrFuR?1vFw$lQ;M4FWqZ7mC!craIBH9l zmk*oIRFs-tE!UdqtBP#S-a)!);{erOOydBY{K%i^$=O_tnV!A8%JrJI%xP_v+FFDg z4kxa|>=oyhGcz^u{6dTPI_EyQpkf!xtT;DsADM)rm&!UwikdQpnXR47eNnDN6>1Bb z=!^ojWuaD%EPEmebAMEcd@7eI^rkJ$o}f0-fFx63!Z zs55j@OKwG%wh4A3MM5AD_^PcD(}D&Bsz5RtNUkJM_;tB&ZQyj>X0-SW#RwQdp-s>l zqzx}vH++Zy0fHBUq>X3|0bQvtcbn830YhVQ>w05$d!DZ9O{>n^F9yLQPly(6*0-dR zpAT}O%{BuoUA{>&9&pyYn)9Hs=;1;%EFqk*Q{X~OCUKe^k>WY{4(jjTc{l1GY4N@n?0#hezUZ3Em+$@Ez5AR`{q+38 z8^=b;uef;O;`1Y8&g;*7^1`v+v$E1tK6#>NR`v~)2LsyU51)O3J+{%YFT4K1k<5X> z-Idjql|6?aist)1JNo&4{R$mAXvPrqOv;1!A@9xr5`bOJe82F0)d>0oNfg9@B8h&2 z;WU{U?jT2xhST309WlCsatCDe^#{6(PCybvMMvz!cmjRUis{RXqA(z0{NO>OLli;* zK?$^V`LuyvC8&Ht!0^CVKBsjFkt=HZK1ayXEcSrG0*y=C%rLW?Xz)D?!5S=OS#UpZUmzc%} zkRSEKLl12DAV9@1&I9Bie)Iq7@ngQQNP)F}-@h@bP(Zt@fJqSrB-cvpNgw)fWm3i- zTzg47DtH%Wa649TD=5lvGuS9jp2RvXV+~hO!U`$h#LaMVCo&A(5)zgZ_D)cwU>U+l zk#%4l(w9LoijhEfRuDEQy4yq;&<#;lN>t9=6x}ev=t4jU&&;k-wm5ARkzEH`d+T?uouB6_*h)JvAF&svY^kpit!B3AVR>CZl~sn1N=`t(#u zpR(rk>(jAnEHtJ^)BCIa>AtEzEmmdr&68(l^x~O&^fT5my))fW^@)N+KT#J+NE{bG zD2nog>|PYCNA=Uz8}(L8vxLJRwg^jKSKX7=sy*rMYM6woYC8H>C^Qoi^w7hhw}-wS zl0u>9Ld}pU3j|e?CO>x@9>xdpcStHoy@&Y7HhI2LDJK%eZGW>=;@svI!|nEA-lK8$I3Pz+3OVfa(*k_+vq{o+1N-VE^b`eO!$^77aP>x KLc*~2T?7EN|C7c5 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3e198c19ab83c3fb2858cd0f07a626dbe99cde5e GIT binary patch literal 12412 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 xyud-ljDf$}5bEl=-({vT?-@DTt2 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..853563940a03e52ed574c197e279c1755a53fc53 GIT binary patch literal 9956 zcmVsnM3sBLKMaC8 z8^S|1Y+E`#yIU!w2|CTAs11VCYEje+#%Y!8|NnZNj3J<~Y1%s+VasZSIx$Q^C|C%G z;@IY$*z_RlG!iP`K20yWMJmck)f2vn&x>0ksOXohT2{()az3me=)}sy zR(Vm_R$D*VyzTq2*=#=H*w>=0;-L)QD$g)HYRmefHhx*s`#<)ZKUC_Fq-fr^Upg~8 z2f%x+w4d&u^J4F8j8^vSOtQGNGOU;%via?sASP@b69J2?Oc=# zW9`;%?eA^q0Riwl^zQw3vzf_%TeFo`gy!JsLUtn%4hur#F$!TY5{a$qm+@a!lS;ko zawa28`NSV3rx#f?Y$(ko0BHvY>8hNm^|A7@4Uczy%bI2DTW-vsI_o7FvVKpp*5|qU zx@)n+o-4xvf|b`KInEw5)s;jgLM7SB=Fj|HZX{3gbv)3|?Z27F4Qm-fWeKtC9#R1w zVt+Log%4w)Qr{_*D}VsAO&l9Xcb{N5ff#9Eh?bT-I%;W~>g*+M`EAuz7^Kt^b;eyLlmK~t-HR>zTj;}GQkTcga zaW6pi2RDZ?SCQ>o%^@ZV$`%A%{hN-|p6Og<@fpZ*Tt7v~-Sbv}03eRG)&vLuD8Rsl zZHI1uCGPfjKX9Py-@xqD?Otm3;vWD=pS8-wl)}ScC54c|ZUlZWXDQE|bGRZrDx!lP zDbWzeA8M|z0|un@ddHYZj`|qhmA{4?hm8U7=fm2)#S$Q(T6cCBEn_B3;Q$iU+MEST zR;=x?t33VYp-xLAJF=FIhsAZQ(=d^SPQd^0U>e8#SFcq7)n?ONle@ZF+8wA5kwW0{ zUkAfu{XT{`l0k(eN)E8+@%OD23unYM7hZEnn~ z0hVy&Sqif=btOclkTFAuQ6p(gzbM^Q&YoT1W6=q&FN~dvg^$LrbbK-+M){G)(QCmZ zo<{X0PcRaS+*v52i+QZJjZURfwidUL?56Qyn7}sz!3l&U8q)0;UTA;vn|nD-i`hJy znCJQ8fr0AhbKumJd;Y}BL^#GNj=lM#2pzY8lbmXtAoyt3DI+B-?lTDxFd>us2I%t6 zzn4~hCMf-PjRQ>p*Ns|>vY}?@?)fxR!?~`%<=dMnWH*S%pWo0+8CFg9t#0`TS;O?# zJ*4w8xMcaZYjiT?+5-bJ4JwNlSWbVP)di_4@8{`W5*0E5$$)YtrDUKj4@DgBDq+{m zlF@183dr%uf?R0p!}f*ytu2>T&RNODqHCPTrZvx6+40ML*vrtxL#=F%LnOaT#V%W+ zi^nY*C5C)xLqfoj5adWm9R)k{u*-M8Lyq#1bg^3H09|ApXj-LN=Ue$jScFQS#pdFXtRj8qT{>{~Vq*5nE} zO!S9TYr)#d26`sza@Ovf3sjI;glkP~G>)EZq%{HtVKYKzS8caVMZ+hN8fTf4D+dK3 zGqR(hv@rx3?PHTGWP+MN1R8u@MS3AcL63P@MvTFbR~R}`W` z0hx|W$LeN0qhKbFfN5!t)}L^2eYJn$bfc| ze}yFZ1WZR#vSG|Ta+8*3lUmQkk_&gUuEQMSX{-R57QlQ}xlobMd{CQx9VnpT90S!2 zLxCu?rom(R!v;*AXx>jzB2=)f}Ojjm02M8j>`O@pFGX4@bDcCQK0 z0u||kaWC3kND%8LF!y!ub$5^nDZpZoRc}3-xCcCB=?#qH5c=SE>C!uuME5*Og-idf z^=_<2v;qr8GV3MHedeF-+o7uQ5fF+3qQ4)hXvbvN6g~lHe@(!i85vW)G2O^xDugDJGZOEzl`r41k5zQ+YOT&bCyd}x&zi=hYTRi4a{A~Hl!<$rs z=V7X0gjU(8$vZG~25YXhw<|YxMK%Cc9zw)#qTy znM+(Zn4=|RWn>if*1OWZ)>SD2vDq7I$i6p3bF-Ojv+zLXI8i7A9i>oWuJVjxiuVAa zfopo-%i>-}>VacsGv-@`D54f+&tHAnKNK74_yM4qYs&JztTu-iux=$Tdfu zDT(h&^{A3BoZ>kOt007a3+kc^xfk33Xqh>ebAp@(NuDyF!l@H*`V^i#jVB1|2OA4M zad}d}-UDWm$`YdmGg^b`SUog~mduin&h}X`W95-k3}HsvkiD{7&}N#!w)-~I-C7~S zU0v1x$m|1fC%-OU*0J;lLPDw1B*$AatU5dZahtRKLN0gg4TL#1BSp+XksyXF8KzUH zV}T;W1i*b81VG5PM~@p%!m%R|;oc#ZI&u54vNoIRtIr!-HvAbTGvML#I_Y7vLfE0r zAPLymK~^CGjvQHn#o4Ab4{?hsnxsIxnNpx}14>C)?7=)EehR>%9Qrd9)tyB#I5AsM z0#HV$U)26uKiS3>#D`S_STvy~9Lo!)^b$J~mWNBkvrb74o(|X-HfNu6^#5+{90L91&lwLQvv{Qz^icgeD=OY}jV=d<$0$cuU?JakMsTgAkQ%lU=`t zR|E8~>&xQ4W+SVBP&p;%2Jn6h1Y9h{27;g# zW$F8G9ey}l=Gjzc2Rkfl&Kxou04I;iP3jD-orE67GEuzS)0HaJgMG|UL6?r=5F)K7 z_judp2@@(U`CmK}{AmZMI^{!9_wyfA2DTGF$<TfH)orFTj)e9g$o>i<)ig;|Vv=D#9Z$&SG77Eg*W4FN z4~2VG@6+Wid(U+1B5WRVu#N~r-NFz_1O%bPL_(DKA!y-P`>j9-K!|-*Ppbz)K2S!9 z@`b+qF~GS0`>7s?FmA%XU#~5NRm5D^VUYfw#>|U3N4@Hh3Mqjn6RLRLgG0t?_#Ec=(ah*0H`-b(^wZ^9h+|Nw*BYx8}EoDOKSdXV0%;2<7ZRS(*0s zCKR4hCEA!2Kx(dx4Un0r9;VRncv`fE9DW(M0mvd!4)8T|1ySrK>jM3I3=RqjE9z0m zn2synMt!HY@uUl}!fBVAN-ll71Hs&!>Br52;Z0!Zx(X*>hw)8kPWzf7P78mf$X`;b zG0xFV!9;i}{E#-F|BX(Rbnb7~LLSwT>~Fg!KmYSQl4I?6bE3Sl@y@Q>=2eC9t)aGu zV+cR;)I3rg+$<9`#yad0>mBADSv6^k`zfAdcOLAIvPkNSGW&!n)E2`Sw`^oI3daLh z)8}Y&+~~Mb#?TAN?pib?N|WN{sTqw#=u#~FzpLKEETf*& zOZuNHhaZAo{quB|=QZ37fj z>IurRlf&aPcOL~Dy>jVz))|?Xau%k7Ny`I&1d`t05jm6hof?iQd<>+>f>Z17GcKOT0_K;+oH!TQi>KEy55 z%Y`x2Ze9tFtR3sCQ6U^YluirOK0GL?Xl|G}F}2{v`Q1hCy2iOSPo7_eSIT&@#^Wjl zHTx5!C}}#`lV-%2#Jo9+wD28zy79Dewk_AWBi3p*I%`KO|0$PG%P(`6RWB%%Rs1;A zUG*1HaT15*{6v2MzkBj|W!ai*`Q+EPyDz}6mDzIcKwx}LZHUd;SS#*ttSs*BP&P9A zXyzmn{ziIMdTg|R^w2a3RpUNbz|~$2jbbPuoUJ3!PG|JXRoOqg_V|?thKt!4_%{ZG z^NqP|?+p43o)nShFPG%tbv05v_4oJWDc!Tz&h;M|n5=m^92I!i{^Fm%le0J0p1ktB zd;6~A$l}{#Hgxo}SI_kxOS3yqhH3h0c^A(dI&cQXQ)(#8ZyjMX?R}=92MYD(37^e> zlF6?aYdmhq{=c=eH?RGke>)iKz==7BduTm#ruWdEb2SgO!lEu9TU+uuw|Pwtt(_5YtowcM{i-1$5p|83NblCY_1?(|+SB{4Jn&t;sKueh&LUzUY?H!}_Ge34;+ z23K{LpsNyU2E+EDJ@d-z!`*g9?)BnTfO*bX;{Jl`D!c`_QvfO0Yh&cJ zRQovy07N$IkysI>qhei&m*Nw!ik_elmc#^{>4H_odTakBR{olQ*M=)A-ROpNk7Vdf z-MnI$8pYl`@1*O$9<4}{@@xrQMjanLTwZjuah#P!(on<=QhrIq=RF+Pv$LP-9T6Xo%_3Z}xu69V2=%{}PTc52yyVQQLe`?^2266cT zg$u)=)U4fH4rH0zu4ZRlxeNL9@0;$krJu}=C7n5F!3!*?-ROaEhffVqg6s(c4s`~baXSMt@&Jk@-!yOKXv_tc8- zpu>0a%&)V`(zZocm_{0##vF-|oEUA|b>;#AS!9q?ncepE$aLmWiya&;zQvf@EZHLB z_hj|9(V|sIL{-EM3(DedVu~W{_W8!%L9{{PNyN>s6=m^ah?#jBF-_TdFZ;y~gGyR& z`NbUb%ZWG>e&tgWwC9FnJg=i_O=cBD#$^V6m+A|6yv>>|HqHHdB5{}65Z09Gt=hx6h>Ii}ttpv*S9!#K^i5ICe0?q9eyN;i zpZ}qvi1T5t-GB7`lG5-E_CpwkQ#5d8L=gu^11lY1>$kJrhrAas>(A68F^b z{Myz+(Rm`JsnL53MD%TrJ<}_{A$PLlGnA)qTsxWB=b;~8un!mTT^1vws7oL*E*i;w zvbr_>2?zbdkkF05dB#+H_ZB&Iy~=#k`{p63|Mj@EXP zB+M6X`W3W+s`GiceThz3LB%Z2@Vosmy0czT80r!$G85B0MZ`Pi)2C{>25t>r$x;ea z;%W!)gxz7|hqY@Pvp0vi&_uXRu_%*x?CP3RN^|YFiILM{WJN+1Je#KxY~Uj5%h3Bt&cc}ZnNEpUIfDamU0zH-3j!sii6OQwSG5pe2YK z2WT}gS_tW448ceodM(^?=@dqgmUsgR6Wb=r%z~E{B+QHH<j#R8++~S6zx0!4|Ls z5{72!1#6{J^#z3sKfeid!^~daRtGRuLDx5Ki@jIN3p$~G!oLXY^#SNRa013qqS34> zBz%T+SX5xgFIy1>2E&O}5(zj7sjbt&b4{F&WhBMqTHeZ15`nYwui*9STP6W^YzpSL z+vP&*rQyvrhwe`vN&eJxhu(MSJwGthh}97>(hOj!b#G31GBhIU)^L>Wh|Ey3WEerl zcrmkch^F9nGrI@L^XXh%>^y^%{UOu+V-xHtx03+^#!~!h!@MM(Sciin-~Jj0(Ok6J zU_f^B1f3=9cYD$a1a9wIKCHgQ%cdvO%tBBN6f7${91A{f-~!Y38|b6 z-k>9vwClQesA|JtwgQAHv|4D^kYZz!<)4Hnl-@u27B(gdh|sFXtl;(T+fL;7V2NbN zS^8^fN*AaLxuG_&(Z;yCp_A>{yIGp^?vd>M5&=wK=m;!%Ia_c^aQJ-5@8*FWD(p&) zIO@CAX+L=hj0x?M1uSOX0VAd)t0Bnb8A#IBj|@l%Fq(-f@fo>H48^(5d|o~z@55H! zG#MIx{L%U4bg2X7Fy-lN!i3WlVD(}A@CEnt9g8slg~meZ{`KedV$)>rIJIN8kL}kH z+lU+Z=m$Tz3-x-8F<~mhTAZGY;fZmqsrFLKGZjH39|A)O?B+(mZ0|+yB}_Tq1t?`9 zS0-AoP(G26IkXyk2QSk$nq`d5bzqh~JB4YzCfR{HUdMPP@HaS3)M@Dd`f>SKVIFZ3XuE@SR+3EJ4MV z0yJY3Ayw)FIBc7QEJJN6r)P3#oZC)Go}u`?Sy{WNa5SI=pupg*M7$9CnU;spktDF} zcvjGdpio(yM&Dofr{|YE^Na7j(%LD-z-taz-{h2h5);f;*@^bscCFz*u(5(|8*8MC_lqNExnRf4;10@M)(i3-w zcg5q8D)HoR{7%z`fmMhEWY9aVtR*d)u!I)d|7TPfUtxM$-X>Ig6-6pBOKHR40e;Ygm|N2E5$ZhWVsz21a!Ov4e};%< zjjY1KI-dmgb>Bo7d;4iP3X!3a=h$M=i__ogxGv=c!~P7{&{y5M+@8Hk2e2 zYtL(o3X?!A0`MwO(6r_X~B!&7! z2!nC?0xd|dyW={8XQy5fAWr_yjYU)Q=9x@5b`D`@>I0ejKNy#@3a~q8884Efv^0$f z0~=1#a5@}@p9y4e7_{S6N3rtJ1__}?L*Q?~-86r30U#UR-duP;=6rf2=TQn6mm}kd zfjDO}gEkmGwakE$lJJZpl~X{^4~;f*BLRA}N`Z4rKuF1|&_|(N_cXVnT=RH7m^iGi#jD$VeRFgDz>n_5&m8F@_Y5dHR85`hnN%z`k7kc0r6;bV=Gi zWK)iUAl3V2v|yd9dwA-0*_=263N#u!6H?+!k!h$iRpL|Mk_}>kYCssPH3Sgr&FDwb zx8n1*%YFpq2#1}oB*zvHov`tDDt9V~zgz1tcuk32Skr6FpYzIr)7EPHpvb3|NZoI{ z(=E9^R=_ZtOTvICm#N)g?&qxogBFY+c$1z6@I{W?CUrsJjlakAQAJe{x+p&6u|rzq zI~`mJPJufFP}Z6UNG%fX&7^5Q-B2YQ8aRjT5jC7Au&>v38oF|`Ci?Y244Ux@W24`T z>9lBqZ@+isjhWHaxvR4evO9G-W1NHD)2GsMfE*~otmW3byB>Vc#Do9YhJ1Y2WI76` zKFmX}CWC%{;PsYK0ApNe^Tb0@u)Y-SSl0n`F`ayJV_tpY*D?RNd>9<33o3OvOe;(& z=ek_d?ad~it!k@}Os$=D$o7U~<>Lp$T}hZ7w_V8KtwB8dKT9GGwd6!M=lvnW{=J)zp|#qts+pf7nZ43>iB6p6Nq@&+vdjOaY}jOWCqaY@ty z5z)9W^&e%F9H^QlG(BCm0+u}OgRtJK%~>${9H3-U+a~%@Z4zr#x>gp&EDdzal*}V@ zHav?Iz!4A_sQ(8bhUm#%01yCxI$x_-uRTsldHzSqw)j_3#k*(uC&R7%%D%3-fAg}K zg$+RDcgAZ&0O6YLejtMRY5V^;wn#X(c@ncO0068G&>2i;0s%PqK7QK~ndb5W7VU2_ z-k2K(^UTqG2)ewmCkKxNxVKe=7j~aj7^(DabM`A`42N}3k@g9({XZ`KuuO=ST946d zbEE+W->1})>R6#N)eYp}Wx*bm)UC)ss44Gig<;zmL2^_hSPOG?LQvCBybW$+=4PFHVF7f2M_|kW`bDaI1;O3QxA(zb?Tc4FqnZU zi%27bP3{&|G2NNMQMH)cqSzH*hol?yWF(^auq=Lc)MyxkLas-NrRaMm3<<9X(J!`&Uf*g7rO5&!@Iz#+O80HAh=h=_=Yh)6_4L_|bH|Iyxt?8k3J8QA>acW`hM>9%&T5!Bhf}?rTVP%jp6VW z`O@UVqF@cHa6CL5Pr3{uWNB+3ZG76d`bhTbB z{D)K~S1A4dxBc1di%#!Hj+{^84yKav1}f&>c@DonTtk)lM4K}HdaiY89H1c{Q+C1Xgz#KOjrDh*e< z3_O{^=D+MD_nEzalW}AT5J88W92PYC0gJx#WLZ~o^LX|^^?24yeZoZ9Wc2z0!ab{H z$~_lJXOK$uRfxLK*C3m8rs;IL??x17vPowjMNt$*Q4~e}7@2I+iTedo=_t-*lg>2h zL!{DCoXIAgeJ+>F<#M^)FKe)e!B#g8_Xz7ubS63zor%sw84+-3LsPw73?e=pXSVA( zYy`aQY#xU#NGnK_dCu|h0*2myCxe}i{O~Z{kK1@3=X>64TKJU_hC*J)kOSi}(Sf@# zM!{Gr76PN*51!+554L_kDk2^e89~NG1jb;@31(C?w8MQI!IY{)(5A`|I(6{&;h|BO zu+Sn*XrMbrji5?JXldjP_hAq;jM$I8k)k0NeJp|lcVdD9n=$f%w*#Rr-vc2gkBq7M z1U;%IL4&FSK~ql&vriKpHKCYUGW+J-grm`QbA5({LcnhtLHqX+lsM)yxH8E0YY+rv z1Bdu_u-T2GY%Apdl|DYQIsiWPOgGj_yN}?VJ8bm_#v{Jo`|#=&j33T$zH4yyusyD; iS@mIG6p4NMG>T@PK6@S=i_d1J(8fGOBvoes0001NUQ>4f literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..acb92ca3e914a814e4946c41161b5fb3ae1d991c GIT binary patch literal 17520 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 L32R#QSpWb41<)}B literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ab00dd46ededb256c777cbd1a278e6c20f253051 GIT binary patch literal 8416 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

        AotgZ6d+#q- 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 C(i~0z literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..96ae7edd3e4d4bdf60e0adc50a816c31641bbc62 GIT binary patch literal 16152 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 z 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 Jm7n+l{}1w);gbLW literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2 b/public/fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..cd40e6ac9e77459a84a333a0fe67fbd473aa28d3 GIT binary patch literal 5736 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 aYfFo-Z$V3In{OU(Eud(2HGGqVO#uL%L({kb literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2 b/public/fonts/opensans/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0f1eeae6cc213d641514885c2efd0438f8b88724 GIT binary patch literal 16868 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 CA!j83 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2 b/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..97af2592f2181ec1c18d1cb7aed4aa5c096f0238 GIT binary patch literal 2332 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2 b/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..d539aeb5ea8bdf502aa3181296b57ec7e6749b3f GIT binary patch literal 9896 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 aGFeqMker&T>VZ>9hJ*pYhp>1c0001X=h(CW literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2 b/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..7019bcecdeca35bd60e7acad1f50b4255d3be5b7 GIT binary patch literal 17608 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2 b/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4111b36671a856ae9c79c24e0b9c1250604c1064 GIT binary patch literal 8380 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 SvnYjN^HWGJ13qZg82|td7%%Gp literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2 b/public/fonts/opensans/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..8993a4de6b39e4c3aa3ca12546700362fd25764d GIT binary patch literal 16164 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2 b/public/fonts/opensans/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..1fd235c2d3d30c5a545048785f9db2ea1eb6adbb GIT binary patch literal 9676 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 ab)kb)z25LcH12#3l+gg_#ocOw0{nk#e8;T- literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..1503cf2592747dc33558091ac25e98353e78cdde GIT binary patch literal 2332 zcmV+%3FG#6Pew8T0RR9100|rb5dZ)H01qet00_bW0U4SA00000000000000000000 z0000Q92*QA3l93_loX_f z3zQLfKx(r+rtjCIVe*h6P5^_q%tOr|Tx<2k8`4xtrKa0nccR!1bFI)!N_i7pD7ALHMd?39Ui=SK;@5=ve?#GxpEU*jBw(t(1=( zK6G%pbf8$+pEq;aOxoDDchBx!Q@mNnsL<_gIwgdyJ zB1@t`2@EkLj)_8oMe;5;xmy?>VrI{BZg|M#c?X%xFl!c*yin*4;x00WVGRob%pU-i&PG-thtyqh*8U9{!3xy>_zGabxK%-^x> zna=z|5x*sv<=KVc@DTXHmI}2v!?B-V@=5<*;tZwz=9EuCZ8dpY6cVO8k4MUunbYHO zdw8gbZ9F$DK~`NF%2`xIwleK&!&T-FeaO4EuEA+%Ff`BS-QyMtuG}>|!SuW*Ffxcc zcn){m^Ru3#9nRmkGsp&EiTi=<-3 z@m2IZ&pV!%=Pd6zp1a;`oQ6;u_xw=EyJR{H;fN)E?t1e*S9Q!^vr%)F$&`KAq4Jdy zwwGruq=`IRc6(sae;<$Es>dVr6&)Eva7sj!&#oAcpMu7#>js=|)L^4*Efma+{wx@y zgEmr!sQZwqv#x8{MX|%dhhBBDaT=L>=AuO68n*pIk8>{?VUwda zUlc>3>k30DiL%5bW*Nn#FL_#nC@dNNz3vS*MxtzztAK8;$xSE1cP#e^_h7?ASQxws z8fz9Bxgy_iuU4h$kBxE*uCtU@au;$Oj`B;`!82DDPN~{lsaot-k>1#mMR4YvVjMM} zDVdqxT{b6|QQ1&DBrH#vxCt*?8<1-L$luBI=Tfi}?3~i)bY(3RlBQ?PFJjEm=aD&! z%+lj%*y2q#w-)T%ljmA0|45Hx%D$(3)T~mKm&!BNtrNBkLRDLd2~$NZw{+JiB~VSM z%%ZwrGa;=buzZ1eW_MbNN^YJZLHUHajiA+L=k`y;$yZYJdxWlKd7Hr3HP_{&QgUjU9l_kR9>ojiW%;9 z1*C~0!mVCq+#1olB)MCN$l(Igd^1#ezG2)c@W$}KJYJmlc-7j?3En&Se*GTrY8ZtQ zDb+H=Lq3I!&&iWz-$<@kov}7F0QO|fdX^HJbuzZUo!rgZU;qX|MWF*5Dh9Qn3aHfX zw!UEiG$@qVF+0_B>jZW>)j&W))tcldjbH;PQ6sVjr&83Y>V_GMKAf&_Mo=;W;Te)@pJty* zRw$K7x`=4!2GZ;iBx#u1tQF@PvZ?lcTKBZyU!|MbgTq6f_VZyNKtY9IvndRiQjoF@ z$+2>hvD(T|&7CONh;l!fiee}j4cr^KTRRpGwB7sg&qCLJAw2TS*0rDC)%beLTID?C zeeK?dzIhD3_BCj1paIbMT+sW5d#vZI6~0yrhB{v?f)oc?TDtoecW*m+<@;xs9y@Zx z`i4^ zQ8GCh$wH^b$Bd2$KzB%%y8`Xg_P8UQb`;uS-yrnZtr3!nqapF0O@_hv-tL}oeJ;%yBhfKs{VAQ z`)&DozdG>t|Aziwa7|qU0)aE!KmgP=LIpr@jbhkj`E#6zn-uZ$@L^~aI{;|xQ9cQG zhMQL?z}=kpRltKTut-2bgHbpR2#}V)R9S(UQV;`cI{F6YNMxP7%&%1k2TSWpvr@vqky#{9VxpRUhf$tE z`ALNO%&g@T^0fWf+8SiGmT;nKA=_$~aK3P%ZS}h#W3R3bMi5u6o?N{RnG-t_drks3 C7+W*| literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4d8eb8975689d41bc964bd284cd4eef5c76d440e GIT binary patch literal 12640 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..bef0033fff8aa5cbeb51df4acae545d105e7bb65 GIT binary patch literal 17880 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ffc6ce4387d508b2e79cf51fd68cd410fd146eed GIT binary patch literal 8528 zcmV-WA+O$dPew8T0RR9103lES5&!@I06-uB03huE0U4SA00000000000000000000 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 KC8Q_L00001_GR(_ literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..be4c25b4299232febd93f9b7528642869d60f16a GIT binary patch literal 16276 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 EKejGBx&QzG literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2 b/public/fonts/opensans/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..cf04c330b9d12922b9c98165050ef38d171d34f5 GIT binary patch literal 5832 zcmV;(7B}g4Pew8T0RR9102asq5&!@I05Dtt02XEd0U4SA00000000000000000000 z0000QC>snM32U=vykfph=_AO(V42Z(PBfp{Bb zD<$mMOSm1VApLZ9M8#-QQIrkFyX^nJ9yf+47-&`N4;e}oB0@2VRMM@B z6#(0*A6*)3=imD|x*c6BSa2cTS@a%|ic@Kmrj*J|(Sw|6|CdT-@|rg6eTznC)!@7w z2l(KRx?Z33geF7^h5BH;gYmaXK`tPT*H?so42>^60pMt^1`dnAw6uq10q>mzN@ zKD0x-Y#m{c>QqT*I08FJRmywmuIQ3fd1=}!tCU@MpuZaLZVv-mla!C+vL*_+EYlk_ z`)i$Emubr71ObU>2HionXNc;X$*&SBpHy2<^ z7!(|du*)DGkbE2gm{S0ti%tFgMsnN%6Q=)(?FkE-3WTr-CV=(>;^}ncj==2zE=iCG zT?!*GIh3DK;Pe~xQ}mC_4Qmb(=m+R0=%=r$c-iCi06boM|FFLm3LxcH;z?P=LI8-? zLMnba@+?6@r5Qh^|ig=lnxpFPAwG*ctNM z6};t*1Ar(iCH8I2R!dGXcxR1PQgB8IMi9KueVxbdot1(!N`T1ec-Zf@n^jxd++=AS zX(a_`NQwQz5+Lq06=JBS8EVWr^#t^hwRSzxm^y+CX!m%rhMmrB9%cj%sOA@EMUEo{ zYHCGMs>0gXPw&2c9FX2-5wxL4CR);TW@4uqzIXZ)FI`i>A ztVy5qgWS4rs$OQBoix2@inOZ$&#fA1|rB2Hl~yMyVz z4=}nZqiX#jJ+I=-CSVzGZZe8&;BSu=n|-mBMm;l?po08{sSD>U30KpW+7l0)HqGW zTAK3Vg|^tv*_FP~ukM3e$b-b&G-|hY-d{UHy&KdM>YN({{?L$WA6iw`Tb|A@UH~UD zH%qOzJMu+z0XOLYHhY$+l+o)0(_E+7lMb|qxy8t(3;HRQ2JJ`Lm~^9Tr7sg}x7+wE z*fTrq%HE^=D#&lIu&d0rxqh2NEklKx_GW2?UUPDZz^#Ch5h+XGZ_zB<;Tgv;(tpT^ zSawXEXJ{S`@KNtgb5mhfNO-+cG1ffhppoUN6jKlfV1z8#Mm)SpKzeYnd3WnkB@S{P zb_^{c1AOo1T`*iSAgG}EHqgs$2)Q225mws^ajPT9EH6RCZmo`tY($)TB0>SJ0+D`_#>L!<71cK38g_ zkbzMJJa(5n4$NI3yzDri$&ZuTXdipT9}S!JBp0liBj4)fO7#uiG&><*+WC1p`i#Art(@Vj$)xy zDcTAss}i6QCCQxG>q=^}qyjaerp1hqIltxKM3?!AGd3ai?KGd^GH0;*MZ1srD4$TW zRvyI^x?{HH+s&GP(|kM4Xy_JNF`Fb&PhM-FqvHli!qOng`P8m?XCG-kJ47O0@5hPb zeMUl{M5XdHP2zHsrm$HSdZ0WAm8FVD{1B(j9+7B0C%(PH@GTQzNO0_D>BHS#;`Z6+ z%0B$J9v(mta0u>{L#)-I{3U-dAiM_jcFr%HrPGQ08;}tzFj+9e1f02tkuvguDL^jA zB>bPS4oBgQ@P4-z^{kOp;>C>V^XfNQ4~nva=%lGtBj z0rgnO7QlcOC`G%lZG4XYH@@eY0J+$8SBcFk@>bmtJp zL>ja=sL8$FPwJUqaETf%(@??Fz(eLslBCfImr**DrXUKIY0ZX3UP?K()WkC}Fb8Oz zZL}bk(69~{jUcvo8DkZG!@8M4dD4+f;a|{;4vo}r98;|q|Z zL|R(;vvT_18PPbeGl=Oatz@Q1q4@qAdX+YYsm%e=`*u7V7#C^JBb*}fbM*Uv$-^^c|2i2}?otzwL zn_6G3Z}-rH-Nn{4v%C5F^HJ3e$8+XykWr|q{|#dT66X9GXLs#fzbaq;gSlkZr#822 z3*nzV$bbFt{gD$dEs(|VCU|{#RQ+IPO?ir+!RN7AITh&qjZnUz0-n5C)v{ZIM6{8= zWmVqoyojjp>1#;YYMf~PCfIPhftP~)Mv+)7@@5Bd#9B{YTE|)I^;?Ov*Hu`a=T@ZAIiqfMtH7;cg~w!ICbL zt6ERD!5+Oy*&uV~^KiC5&luKJ4CcG%;B5wsd`Dk<~(-$I#IGH;i5W!6fJv?n-ehs?7)zrxYHD=l$DqAcx2Vv zlVakMYN|APd#8Bwx$Wrj_0CVj2;6gORR&ZMi_vsUq}ba%Ut%1@3^4Fz=rI~^=Jd`N z9m}-qtA9Exqk$c@aw^90s`*u2iSR^)wc`{^a;@V&j^ErRAKwOR7yR4uWgcE0gJvJh zpOTw-6T-}Nl5Le$$e8WCzcg?7bo*bE`jR|FndVm+qnYCEsqI?M!(hemL|6Za=Dvt- zzvEx0K8B`cz$*85Uhahp>@PBZ${5dD+L0o}TF?05k>~f!8Yy^f#`pUvvGtjKI&QxB z<(uis#ydK4u{HwIkXStA%?V_SF|BFEkqzxv(@UY*wTDO?67^DmDVPp(F%~cQhSP|1jBLpYxm*P9Pqm_5{d?jTr!BxP| zh)?&N3qL$OU*f{UeX`GEN04CnnFUqEm|BIxL^nDO7ig;MTg&x|%lDRD6JN7Fb%>$o zNA#w#h*YDQg91!$W<5tgfb_Z*-AH8P#`^-L!i=hZ&+aa-$Pl*gV4#q)Zr&|k)6%21 zagVW?NbXs-h`)=A&M8P}JQt`qd3fv0;_eOT#UV7WfE^Jbh{gDmn8>?ZGs5`gxV!)E z$e!tTHfTRVTx4_}56u=~#Jkon%pP7ja*WbQ#t!zfbgmaKnUyjO z{mSOHJXmIiXVNj1IuWLC=g{K(!70Udq?H*nObgFGDmk$%ri@~CTAt}HfIRb8epw9+ z%m4&Ha^Qm}?2?lerPxveLWwn#<^cd8cg0H~^##{OOVK2|R$gtyH2r7b-hhquiz*lrW-5bP+8yP}JwSjwc< zCxeFmD#*!t8!NTmWf3OpF|1U4oB4i!|CR{+f3KG!l?notX1o;Zp;+J{7(r8MYzCWb z(j-$)@s9&r0F%FhnRiK$mOGJ6Y-7qjCuh52C^y+8ib|WxWBRaAUr=QNfugv1X~h@O zid!+73X}~}8k>!qntc_3Rs_1e9NN>LihfV>mRJOv?GTbh4DaPwAI_7%7k_mAgo#PZ zW1jPVsh`urRDTVf4Xt7#`d^?8wF*^dGoXi199Cs>3sP}Jh>_i~e8%&6ywO;6`1R5W z;|pS<1S8zf*i`=jS_oAOvO@%(RB3FY z&VeOz<7^-i3mF0Un{gK>n5w41DX;`ni2snJrtJMrKp3s?jT7D~a{5eLWdvu)DN>~w zN&tWM!8$SwHrQ}|HEw8%ih$s8i~v#^WGqYRcT<{T%n{JRM?qH4a)ZBXNptFR#|XE4 zSOfhf_lg0eB8mt}g#K>Q0+OQWpp6qCq5bHtbuhI4m!E$UWCjf7OAF8> zLe#qWZc;O9q74fQqZv#tVJ#tLtW@DN@(jUOn}+8<&nAqLJ(K{=6=RSia;_tOLwx^Q z|CKiM|DC`2(IqOO+ilzK7fS7t?%OFzcv+e+rZT51zRE0KLj@n9XosM|fJwg_&el2M z8|=_A)>*r7Q8aHWhwhsRQKl*6r>42AzL;b^qq|5L3j)4?Wm-cNrLl=BD!-m6EYL?R zx^yX$WClgi*ZRw;&JD)NOl_;|mRehubt+Z8hVrZzeQ5}hKhSAZa+Mg_r~q`toP=M> z|5kib%a3sP%_lwD{kIseGh9VYmnTV8G|inO;%(gv5Ia11naRGH3L~=f*tW6&^Die* zZ-bBAFnI6WwUEEm!C<}}hE;{@s~15SHAGRP6Ti6QjL`%@D@rp%^^F1ebN}*;u{ey9 zFAJ$0g_M~Q4?%Fl5Paxg{sc<(dB^k4ZRJLW*mg+)vdHot=D+4Nzge2MTzOTh@4#qlB{#LU@PplQFe2nO=xO$NfYE#$wQ?ZXda z;xnzgrW{LZ?Q*#)7vD~03C%Ehpp2V;y#yHTQ~NO?*Lbm68poD0@c&-IqsV!5=oJ|; z*r8MA>Cp0l9H-s3&9evfNRokI8|9w+ zWc;D)iQJ5XudjDJEpcr27TbwQXX-1L9B|Apxud)*p3sRWN#_%4-`c*+Ub<7At7~Z>}^$q(SQzx&uHLHQwc#lu`9^P)jDP{?#u;2tex^QS8Z<^XOEb!PUTUBTx5(xr6 zJfhQszdUm#3iF73Mr0_V3MlFbc9^hqE#<@WA~|EVnUi@}($Jx5+qWNIYrf$xW%)C+ zS#9WM*+Hb&*5x&`Z}7ndvgmdVxZ4 z`S~U%Ip=k~h@P~;Uw(>sjs+Ti;l_2{cGT%t+j^O%H8;sBp$Tek{4XW?^2^@Vg2??pn4 z5J2$1H|!KZLEoVlP}KJ^Ar19^RSY1Rm3o#BlfKpfLjIfDb^vrO*cIbIX;cQkncv!a zR{{`M(Ygo31OXV(FCfNPV62Qnp?tDg`!jl*!%+UZ#8n&vrIrU`ax9yptr`RT`-{Mb z-=Bux)s508*a^-N1{2me+1kT8vB5lEoSS{-6EjD!Kehk2I^E>a1>joZLL)F-G%BCC z`8j}p8vy*Z`X~Gs%AW@lgI#p8@jpL&{IVtz4&tJ46p5nc zSPOsm`f?rMi2wByTS* zTMUM!O3Y9RcC;(j@tR8(!};OyqjSdB&Go+lopxg590i(Tn=sek|a{6QGSNt)$F zS=CM3^}{&L%en!GFrkbKskE`q@5g!F&-?uljG!1!kQB|Z950BHtf-o9n3m1%aJt+c zug@PMhRuZq3U%vsM$Wbhy#kZjZPCYN+(I;tlFPVTr}Pf4ae3Uy7V5aqc2Omy@8DiY zSVUAzTtZTcOrg@~IU|39Lc$`VV&W2#Qe+C1Mz6>g5fKrYB;`}6GkBJQLGmR87_7TIo!zJr=?b=SKuy=;ayGAPNkl2*@u5k zNcpnHp=I-{tmTRtU8R>Q#)TqFuX^r`%K@_{?u@`R>EcQG#p9P3kIDjzQRn4~%wKlT zzsRaJn7Yivnilf~4-A{=iMTHt-GGYFej=W5NDc0iZGpp4{$8iOZhOIX2k3CAwiGVj z7RS|q)VS)l*Y~!loiB%3l|zs%+=ZZ)ExdO&?pJ2-VV5vqa#)zs5`P*CH{f)j&Xuc|gF}ng5Rde{dvl;qYuBjDUjdp@K-DbWYVL2ho-EK?f_85h*>UB3@WjmW z^w8L2oLOeRe|~-zlP0h}AZ<^HDmB!xfn&)EqbPo3AOjcbLf|zYjm=$A5H66R>`SzV z5k;kl^plY+-MgYBkZ#3K52RTp5&7JaL~_fsXv>Jv@q=S{WF4Fo$o zzd@`A&`0nqM;s8EKZzz4N+Z=i8M-ZuU-@`cBheRvibcQxp~1#qY5REvHYXFWSwuw5 zbKyFnJ`IypOAJj-gRIAlV8^0fW3yLfpkr~-?qWaHZoIf)OM3Yk=9sCmuhF>%yMhR= zX(1&qm00eaPL1X`^7IUS&8D(82|Z%^#|cjZJ2@-q6Zi58kvB0osE1Wl)dx1FriV3X zqsADML{)pUuJa#$U0|#2Phg&63nu7xG7?ge95k+l(gp%S8Ram>nMiRix6q!$sdh7nN13mFH`LIAhTndHWOcCd~vGt zmu}=tkcCqJ+)5^$haEtpWR#-pDZs!jq{=Xw@>}BWtou!7nqL-;!qrr12o~SKn$!>B zU1e5DAR{Lt68rLvU>&}>+L#^&oo0?e9=$mvUi*Mn6|!#`?B?kdwzh=nxu)Ag*p;l zL-d5l!Q|=bQvrdlD+-IuIk<(qzIfu zna{#WXj>X*KxbpzGfP9Zj%!E^M~`%Go#T6-UQ3od#TM^w^Q$yuDBDI%rN zR3A&W8@37LfQ;<6HZl7^17V1Sboa(ZSpa|9PS)#>*WJ#z-A7$^U1nti%*pO0#fI{PpW0V)LXaikl<7YPRQ(IFPits`4U z56tRo+H=^yLB==SSmS5YeScJn_|Rl3{384@1GzPLy4uqoW?d|cP*lt#%G2{KY|=61 zT+98%yLPL2`vCKqBN8Y`Jog8^KeH486s1qu!K%H=#>GD5`okFo7%m0$nGguhKLR*B zXYHlZFu?M?&d^11KREr98&sqh^AnV>&ih06gZRSEQeU3ATsmJU(lE%t=xva8L}>LV?Cs_(7_&gB#+#nt{#l`eHG_UH0gjRA~~Xmp5Cs74EE@#3AO`*SJ$**TKr zh!({6UJF5BxcSCfv)Fl676BxJu+EpPU&UFqGd$TX-tRF;&1lj!lho)@*IJOzj?$jT zNauE8*QMwWE;!3|Jd~IU%AQAaL2n}z=w~f1l$cUJ;K0x%QruBXdN3i{w8C17?qfP3 zNvl29@JlwaLO31Ehre`@h)RK`!w-0tsZQ|{&P0h&$l~1}HTeHBS>>7zk_S0h^~|vi z4Kxx*_8i+!Tw5%_lg|S$^BiNsdvQ!f1Q`!%ja4fD9qw!_5o_G>UTFvg#iN8tum$<# z9I>Pk-noRgpr(bLQiP6Nr!d4GE4arC0>7Bn*1b7{O<+ntBMfdEUm<2-aVW_eN+gxi z+x}=gZqK=Xe6&!5a%!tehq9tjjImMUT+9-Is&zz`cs)Xq3Tp|P+}r}oqAQ2UW0fp? zU4|Gaozg|l5(4~MvyyYgC{b~Qz)n)^ztk|pbvCMf(#LkXLqdGO3M=1ZnoTQ2p$FTC z)j}|Vf<+iyWw5a-uzu(Ib(ES{qI+&1Ut?8QmL3u)qR=;#W!u7~BhWX$oEi3OMHXcz zYvIBoA3K3V8gTj$_#_LmL?lM+G55H7iUM{aoqE~mxPE-Xr);z#%1)bXVGpc$dH&pD zMrd*q9~^7%hQgbvbinamcX~L^&?qyvC&WjQBmwm8fhYEzPd;Z_TqV%hKqDw}JZyqHPGXPA%13buho&`e zo!-iPM(Ic}5WnUKEw0Yn?4QC~@+-BG_L9CXsYM}YvRf(hBFsuwGb&_}zGa5OTO$uI zr|qe8e&vEi#gc~l2KUY_KCQM;_o7GN_F&^WX-R`IwuN{OiQM+8Iqj{GeZngC?PYsy zrIurTft7+wAZc|7#N(RFrjToYNsf^~dGI`srX}a8=`3 zug>BR!Cz!aZs7iW;9%tt8|4*_P|=_&ZuqL0FoP&L<*i@lrxg3Ix51jMSx8bOm zt|>6!xJ38XkiW-T$h4tk=|kj4;3ehba|i&$%z?2hoE#;Y*Q!H*>J^I=0Z~frDYA12 zfPw8SZdZM7ip^*)o%TaLw_2AND#pF5nLYvT5+%|On)kia!V+Hj$ltB(sFu>RA-!5z z87c=UoWAakCW!2$bj3@Se*JF9vMi;=>8od-@nOMRcfo6_mXc?BkHDl7ODaC4%8>IG zNYH^I!{F722~mM1#9e7WW|#M{ybs!qnJ* zDSpB}V|?w>NE$rmJM+@BU%%~K<<}rYP5`a{&aBR<%Ep`9Oc_cH&M8tjd~u z`=^*!*sX|ly1K+#pBe|O?8B)*9hW}>@-HPtPe~Qpm9RvKfIbu5@RW19%VYF0^!;Yu z_vS5MS~3G(&FKi`gBtW_2-B->UC)^gA2F! zH57iYT5~g%cDycW7B5?vV7>N=FD`o!C~f)^w`6t zUxn^UMeVYW?Rg&Nd-dkD+5JqF0O#dB10;F;Ra5PxdEMFTCW4Q@Klg5H}kVKXke3%y}u&B7PQrwbat(H z*=c&dRR8zIi4D2g`P2Q(efEG-P-oF|>7pp;`U|QO_twzt4ty)@l*n-n7_)s{|H9IX zu2KPNX+=M2cc6eyhzu;%K#eXNgMbf~5DjPJBO_b^*wG<;h)mQ+P_N%;x7Q1FP35QZ z<#m^#9619~{gI|k2hiI02VatkUMn_QzPkTNw^vVdH>b-p@w{BnUn-~j%%ZWvMM$qm znDgt&!VO$-0}tv^dt}JfO>h6|o82tO0d;YI?fXC9SIJnCwixkLU&Q6kOK?gTH)}^3j`nTk$BE zYC>iiH?09Be-JJj1tqI^J=?VRP|`1Gd)WjzOB$T*qTQ@u!^x%V)lk)kQsmN~g%)S~ z?%FKFACJ1QqQ_0RtUC7SeDoWMKgN6@UTn{K-Y_yhZ~s;!D{ODua>xz={N9t>n3jpxy$_y0LotAOFBv?Em| z{B!`E4%$mFDWJh#^8!jYKDi3=L2m*^r2}4)4ApnLQEL=*%Ry{D*yHyR-c@;(%-`-~uv->R+ zUEM`QkD+KY?mh!iaVJaT<*|qO&aKPCRqGV7h7!S-?~M{s%gRm=TA|Rhmv#rB_&^a2EPEj`uO^zG?lNi z9PpyjL$UqlX7b=*>#Jx4%QWpbf&a&sQk%zy-B z&dHsb^(x`nhP4A86sFtarrl{0%J;m|S@{n*S1exIoHB9OE7$nT@AI>N6jp+%lDV)p zu-J#}V6Rt91~?A>Ox|_+ncOK|yo)00AYlL(g8 z==nlsCv$l2;+n8Ede(1V!y-A8_yzAyYP&r*uB{Du92t%Dj1#pGg{!IphYa!aHTi7o zfVIrtpdBrkSe2MOvdKU&6-&w0`H}}(g1NN1v>Ml0Ou@vMd7kH7yi)9+P3rX|4E|F~ z28l_@6TTW-E%7Xl@PhjV;)0qZLVLWIAwslZ2mqj7 zpI0opUOYntj9a{y7MGHxwR9P?+N!NM7GEhSq6cJaItVQdP~Q~YY6C<AT)5{$XNrHw@!CvZKGc$#v#0ss3Uji8r-G1OnF@#>@5~O znAV1P(oD7-rfjn<!Te;S1uIM68|OuaP4?a&&SwM**g4#$uaVRaH}PL*d% z;QXDkFDMwF=Zf36@BvsHAzGr*C_N3egFCu2GTNRS>wVwBjpMRX0~GD+i*8NyN4g7J zS2D|=#QD9&YX>HM&JG-zr&mRX9bR?H#L9Zw^m~UM^}0v3PU4k_)q7+GWq*<9d$oXF zusyvXURQ*tw_&X>(@rJNdtS>BX)Cjjs?Jc1@sf+rygO92iEEII06(X!T}!$n!bhiV zN>K2jsDm0=pm~udsY>azuw8GRs4Ws1L>P$n7FGrJ@^Yz3T+rb95}qe3*$R+zr{QH| zAYy;`nUxC_T{T$P?>G`FBIKm2pm&mg9$Hj&=sW_~{p}#e(B19*3yAsq{6f?b+BM)I ziu%RCLLZh2KoB4$4;%3hU56fj6oN=2s!QH4?TjwCa>(XQ1+Y+*km;3@DUTNy zbHR|a6AviP{*%K*32$%YtruG2A9L8c?wPS7vv4L~66b|qC{YGH-0NPhnsn+ap7KFB zHmE3)MQ=D{GJkZ_G%9^qM5xZOy^;z?$!%>KOc;b`RD-*Fmg8eBcRiTL23jIO8dmTr!gdM4Jeuo@(d(YB{7 zrX+n&JC;jH!||r@li%Q5l3gJt`Wb+E-OCq$SVk{jm93IKRMZL1BjUY4i2^z`TR8!+ z4=v!=3EZ#RcXla5&LJe}dOql9dD~PYRS-NNBF=xl4^I5YB^H+LfNvm~nc&O@0ZvCg zRb5~y#}YLz`V|}`s$xhS&jZx=o+$Q@a}v}FSW6+_g~FUq`3|TZl91)=1VN@|>R(~|4d1+Sl5AqU(wqRIN#Wqi#z%MTvCYpM*Kp~u@EF!4n;jKr4WRg^9sf=+ z$#e1}VT(O0U8*9jwVdGzRTyhD1zImD;NV<~Q(u}r)rY=J_T5iO0wBkbKTp71A9p}t zxR^mNRwlWwHM$}j<@a7k`9f${jBTT!pO@XKI3d-iC6-po#R?Rwydha;+tUG!Tw4eo z^LG=+tyQQ_UZ+|HF~O}CR=HKre>+O|C-c2;Phr&}TjTEO*SSwA1cUhbt zn0YDydAlj?-+U|KpJ@^|E3LjWi|bqD9XSHDKw~I7np(Dc?V9R(+G@$|xQaA1_S1)) zHcxjFv*H98#c9~8zXb7LsoV%A-^cIj!g9Ltb!=iy3>#e0U8x{Q!1wIg6=aTmAUD70 zPNpaOugOJChQ#k>%+2>*Y}A6sc&K~ko2xz3kC&rZWe!Y!-t^{|t3N;3 zb#0%QQKgdL$5kBpN6<%~gI#;8`T3)D%0gPQNJlpd5c*4gPgOXx)Tns)JS zzMGHo`Cf-cu`9-GcV%}m^7;PHz-l_bgU5hi?nS1j(iO<>6 zZmKUuB8-f5s8ON1rHt+!xF)PK&2E6%j!e2`#7E%^DQCUAk%h_-4i4I!a#*!jszYpU z2QKKZ%J~)6MzE_23P5OV?;rs=!-~RB4X05eYfA*8Mfd4leHPD2PXM*3bA$P(!&X;J zm?Pz6Ob^&%Wx-{!YtRstBDX$sSfyHLDUXWjKm5)9?3eK%MLPDQJ)YK3;F)R;VXKf< zJsnzdKs1L66Cnbo8cH7+uUEjV$OduDlt#WBBBqum1C@LBkp=o1*a?&~w-wNI8n+0=H5}h;&I6yaLjV`YK300XZfKgVxer7*Hz_xpPv?ZV@pIw1Mj;%VnPX|zLo^c zAFG$%N}xbMfmGx(zaD_YJ>;^0Wf~Kl^1&w|P$yf-kj}aA5~m^*)TNBJPTmHOFWr(g zguVf7!;Q8n`M$3<1{fVDE|5| zTa`Kw5kabgcs6VJv*bDGYEsRVsbRkFNMm_meJBhx0WQ4Pj$($x25^&O8Hs&~>#C&S zA?5_(za@;(+*DvWHy+l^qXa`rXcR^!L+M|E(dJ9(ci!_WyTDXJ8?1(wjo6xOBrUF| zfi7xM0=LsS?(2^p=>S1yjQa(HU{yK|LauI5lAN^w;!0k0is>FAe^}VWiH1JOXGE|G zgd~Aff+D4wLm~}qL5{^=6)K2AA4%nsB(<$mn!-v`uWVSC9=+jH+F6`P6`hbVAml>L zXbz5A&c;NNAfA+ZKU6HGhJr>!Rj|Q?V`(X67O!Rwcr=YwQt4x&NV>d3wPNcfXQJ~r zX<q%F3uCWv@X^Ne_p$`*iI+5g3r*p zN4%uXiy!(lazD=IY+gI87bT@sxAz*_&H8*r9MbUh@bZxa_{Hu_eh81)PJew2v+rJX zJzTkRawslw$W~UGwMlcrQ7bMM#G}Xi(3S*Cu-l!g+7TLY;N^3AY@bM13JtfH5O z4jm0Ww38quuYPXf&88dxk(MwkO!&_aom$mS0bN0jrCI{N1SZYf*u@;BNM|;JM=Hyp zm5%Hw+X8)SU+t0gflwfcXamPAR}48dC{W9Sm(k=MtiM%OTyCkZ^75E(jAG7yvi&7UHs?tw*$*JY9Nm^{WeGq)5ZsLEWDn4{vI zZ4im*(JHd02(mv))+g~QMB$+?lfzd*Cda6k#7szaX{0xFj~KoM2Noe0R(HNy@d=?s zC#!r)>QZ*vSGy={2(NdJz!i5g$G@`a_hPo_Ic$vZ7ROD9YXF<^3ogYU;svqqf^*Qj z?cF1{r63vkJ3kLkJ%D*kgImqjV29k?PwX499@Qdh(PE9{K~O9TXbT%e?^H@3ems*q z0Pzhr-cw7*Fnw}mKzy~;mh>os6_Y16WU5yl9m5*$!T$27So)}hl1z)r>$b>yV1pkt z4nvjG*7myn-hr&BC3gcNKW@IHWq5@xCbGDzeHACHz(xzEK{pg5t}(pA%Kl>P^%x<< z5lpMG*t9>Z)H#PCf}~&<$gt8#jA?Da890`AKj;0CzK} z-RWCQ0QyU0i1!>95FMLMz@JL;Irf?Wc4 zH2jLOym?(&`Do2vCyfm8g8<(Xk^Y)-g1+w;kI*|r-KQo zW7${5aIaPnFtWm0q9IZPrhj#id#?=geiMWlT}AApK}AMqC9Mk47eyz4sJXyJ9rx88 z%s>$*qRFuk!i;jI=7Z$4oQ)d$j$b*RE``yi`69s>3zUidyqXzciT2Y7;dG;@k?uFH zr2>mGIg}yG;*-!)J}Uy3{ASkWvMNxb;-)m=oML0TGlimNNjthwYRhRnw?ALpCLEIK z4Cs;(KkcrrY^CR8NYnn{$)CO18SU1dguZ>3!xllCG)H!7`qJy5N@EVw>TR8!@yd)I zv>G!kF+7k-XMp`0lWgG{+SlC^zWAuO9iE}vW9_OQx{0P-6Ng}1kV zQ3y@RoITqD9a~Ecm&dy$#u;yju)yY-r*RqfH1~em@I<^hrmyk>V#4&e^3OdVCIc_4 ziK&vXJi>^5GZn_(tL@ZWJIJCXyShC(kbI!T@8faRdRi=Q%TMkAN6;r!`+CkMEECJS zn*b5d8OVSE9<&UuFYCBOWr9Wg>pgSy(_o|cfpWvootyewqot_rSh8Wn{h-AYr+d$E zxo^FZQvBN9=e-!YB10&n*T2ni+9Ot)0zA zU!M*HoG0FI1duIzTi7E@H_ruVRy~RHf(9hz&@@_4XA%<7y)YtAYW9~z?MOC>weHvg zdWXX6coFKbc3!F+k%L>|+6@Qy`#9d+QuqL{)Zlj0KI4U17!9Qs@=|ZiPn8fnmBz z`~l?{XkocjIh{JTJK41PfMJ=(4#R-s@Iu$1YCR}(@=ylNV+-9`+a%oTY`uuw8Mn)< zi%Gofz{)?z^_cE3BiYG7B~gzLkSt7-`X-Nu2y?CV%n)N-Iiv9Q)|fXt3}~@_V0hWe zQ8VgvK9KF4B#`P)phQ4W6{ANClsZA-^Mp#df->>F9lV{gS?`_kudU6lwAZjGM#rN zk9O`<*x?Hg^i%xUQNY+sR25uev{ z0d$NH5F#Rk80nC;fn$$Wnjd>cY*x_=H{^91Rg#}cG97SKEBd) zOe1hzlL=rA5c>J1r0+`TUEyN#&f+G%ir}5IQmQ!UW|*oiGp1?-kH*#JD4;#-)WffB z@kHBX?0=xR1J8BnLVbxVVv9k})jLA0W}43nQ*dT1CgCZVo-&--;fCu*{_Gi^&4#{@ zL?2<_nwz<*1yAKa_b;-r+M^LB5m_co$P^E=`KBx9VL-H3gG$kPS+TT&9#s!8j+U%0 z+tcwA7P%LnpH!l1rD1kFh&I_KSUPW2MiW;+#0q@ld+NbVM&VoRV8sGwJ zh2e>AlAU;Jf2rL;MP_KNaUG$hSm+HM*%q#^*tE&|sjIs!RLk>Qy^npM`1}8m1R4In zjfF_a|3Vy!MDibri2R3N9o^(+l2iYIJePhrl(_|2qHG+~Emi|ICz5GE1fVk0q0CwcGqxuBpX2 zayYYgegl(IOlkFz5;dC7CO#bg9?qe>Szt34N`vKd*`FBniu+%h%m0(N3(k7ZaH#Nc z+#@X{-Z*4?zCBbV6l6+qXC;-z1y+kjqZtql4tInZXkD7tqy+l1^g5y6G81mt%cK@U zb&1#xUm!Fv$CXN}OSPBw5<6fP^s>LuYdDrx%5y43x&J8(Wy_1gbL$JhJnYx)2d312 zx=H_UJVXkh|N4E+R{vG%)7sPnmP}p%hFu*tk_3zpAX$JsdB# zhR0gEb`HIi5ea?%7pBnEnRww(WG?A@%o%9mlVn#s2B95~j!X05FPHhs1>}EE@xO(% z{^r?B3qnGXM(f?^!{bBZ1M|W8cN`s!K>jMyb7=?#p3R>VFRlmfaf_4kGVy5el4ObY3Q{JxS_Lo=(S6^cfdQPk zqJ)vb`{fg;)M}|}+i64+xK7H)EXVt)4v5MbH|pn*>1MR3v>a=TtoUE~V#}1neskD} zEh^EZP5dDs`8K}6f?(T@>I~1vcR^}ILK~07IQ?y58>(dJNmB&F>%&2(?R3<-uxtz$ zq9du$v*eUG383_c9GX`Y{q2vss8j%BemqbsM?ZP1nNNzQXkHO$C)p`YP+T-rjjU)6~fM)ZJa%+Spm&-W2TgH*@_A0Qvs;66ELYZSU^< z+tDLi!n&^aSBWl_c3EeebGPTVao)CtciSL<2``p%aox88Zh*?2*1Tuk``9&t`O1+m zhjBHFH@EZjFC>BYLG9?vD65y3pAYBxV#;jYP2O&A^LpL1bRMt6cW_uV2BVkXdE+sy zMs4A9uf;X)-&z-`D6QxvF%s~2qb4FHraMGXu5*wIafn$6U;)utqEs=r-LxO?lq^O# zgyY~eW+P5+-M0Ci-4=_2quEV+SY2gOA(RuS$Aq zCuuhY2t85}K zSr`VJ(c9v$=4Dx#W$j9HJu-0jw|3ap`l6hjRjW}DgeDIJ;s7Xy02;?=shmPjr{rOU zTN$DJdDuuOZ=s92o!Z};jg1mFBREmT^QMF-O^AGM1`gTEGu!Ax#shoplH;r-N!|A3qhO z>(tI@#pZmCi_)@qQI{I^6A}4TO|2Pi#zet|Y=qO#cQKeS7}7t>@bYsT&3szMH3>=; zCBt*8J4|47W%J=jb(1iB5~YmSD01Kyy=&oyu=1W5k0N!C5;s?eEt2#u(IevB)HW5| zis(`?!qP!YOVYvUsYkOv2&L|`r}oZfF3Eld41S^my*3?|H}*kwe2lG(f}_{6=?~Y# zs&}P)x!XgNquR>oyg0LdTYvLgsYiW_P`Z^RWD#zFXI>c&o=SGVZ|+^Uc8f=j<;|)c zK5^`Q4=n{8Jg0SS2O0TULPwh(g8O1Qy{`!RdxyIGlaR;kM6q~uURSoRLycSa8>V4= zv;6jQsCla@wl4bp9Qd!E-ZzN<;`#adho668L-695^m@HsK1sZEHA_u3SsHUaUA;x$ R`Zu5MH=Po%BdC`F{T~T|rpW*R literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..72208f35fbd5bd86d461e5ca4aa98e2b67c3c37b GIT binary patch literal 11908 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

        +4w|L%I=3)MA4xL7mmMmgt~Ox-MW@N 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 PmYw*n#pv{ZUb6oOt^@7h literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..6b18d55dce10306fddb5e8c360781d4ab3c20431 GIT binary patch literal 16164 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 C177<8 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..03b166f8bf40ccfd6056b004f5ba0289188d4648 GIT binary patch literal 9700 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..fc8efef1395d0c26a3727868bf5b8986b4b54151 GIT binary patch literal 2296 zcmViGj&m7S>D2-4FHL=L11ekbnsn{0=7i)n4+$01Uv;+--E{b8% z38$%wYpRWyNCLY)Tem=@$)2KJqPYa5%P=%uNvR$}j1L7d>i}7ZpC2exr3eDk`e&s1 zAI(tvWywv%0!W`Ksc-i>Of*fhW>r{Wj$m)0fHdVSEAc+;OwGoKCXVu4$W?T^t^Wdv zqe>FZB#`yCvBNd}k0u;Z{!X=i?B@2n+x53sW)F`>x4%Y2lHu21BL+_O8Y&(K|3 zW_)-+N%!~lbf@I5WI_@Jj7$PJutC(xfD=-ihUJ_|?D1A9XWG;WfP@76aVbm7<@PEX z0tpCY;bhpy0$@~aZD^RD&A|#ehK`AkNeTQ?qNIbHRbDABSNjBRt518S>`vL|)--Br z5wUbNvB7zv71@D(xp3UmU8KeJ?wpBYXHN+|{(8tlpNjFG6WCuX?6Hr;0+Kx{Ukjpc zhih=I%I%V>X@1VEKtC<@dr?tb9VCm;%WAppyQb$4O1EY71u7wY95JSFa zM4}x<@56urdua*wzVcuEQ?FSEla_2SBnI7@juWoBKf#dD6-uIefC%XATODnvNP6y} zat#PYz%{NBx9TkO^P|Y2#EF6^?CiA9Q=-r)?(L19vQG@13^xtEB#OVVu-Rg|l-A)$k;%Y+N6=+6SB zbC6b=!4y+lKry9MI=u&5Wyl7!?9%UDn> ztD3J7mNNxUCQ30i$h&}D?pKI-&twop&^B2{VSK~KC!DTRpSB3FbNsmoHgth4NYLfB ztkda6V<%Dw7$9xTdL~FlfMcl0dSSU~^Uo@e=_+$cBvZE@36|+@E&{1n0BzrXc4$Ct z3;4r~LVF0H94PchF=HQOPwR+)b+ob;(K*_1}r@??W_TXoA_%bol|Xz_QxPHsYM_$m`|1`$v?oNVMg4&$ z9gH42*&xseYQ-C8l`w|nphj{qN~O}s>NX{w7~z$Vbtjn2Qmj|#6Vw>D;bT9?ml&ax zK%cmAA68=yvDUY+gWGY6sgugK#H_n9(o;LDT9bd$i&$ual?Vmm&Y3?S_(i)o1rJ%< zBy(Q#TT$SD&^Q_eK@V48!1M$H8Dk^jC3~Tpt{0$(7KT(OH78X`MOPo-QOr8K4MOo8 z;3Q9Dg=q&9X=zI>6>BywMX@d=oMZg%;D`b_~t|B*yq}iJ5O9=p0yu+^(F(a71?gw5reMxxlzN# z)vC_wgZ!seJ$aRZ%VMUjqJ7ah`m#G_dnxqj|7g*o*YjTPnxQeC8!Jn^yg^DfuY6!j z`8Sup#)abN%=>X_WQ*G;j@(~4^W)($ZSI}eb3ZQK)&bRK7nrp>xxt`yn+pGET6^M< zK`G(Yt`zjedFOV#>Y0!(kjvjLoJ^=*V8i%d5ENi_vEC;B>gTp7(FVStFBI?>bi2Hz zYPpn(NoJ}j3S=i9as~X`+=9#IipO{MX!!9ty$FD$3A1xGp53lNSl(}T#~-4BQ%y=9 z%u2m1bN;XTcgJzd-WZ7kty}`^2Az0D zf-xyCgy(pv%6`t$k!G~Vqza8P-i1SO$yVk zfVRL*0{DYNUB&9Mp^GPWpg}L4nOOS%A!+=X`G%uIelYVJnd#Pr(7%JI(jC%q+WE<#QK literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..61d2a4e54958dd3371ef7d3019f283381927b663 GIT binary patch literal 7792 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 vxF6Nt&1_#>|2s2Dq-hfcP>}xtR?rWU literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a739e6ab026cd8995672413966200e07bebd2d14 GIT binary patch literal 14968 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 literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2 b/public/fonts/opensans/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..002c5777e2314e5f1893034868b9e5dc81a87c70 GIT binary patch literal 5504 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 CxrsRd literal 0 HcmV?d00001 diff --git a/public/fonts/opensans/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2 b/public/fonts/opensans/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..7971f534272003bfb4031ad881aab0b2158f28d6 GIT binary patch literal 8160 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 C-@r2f literal 0 HcmV?d00001 diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index f8973c65dc7..8ee73d537e3 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -14,7 +14,6 @@ @import "base/reboot"; @import "base/type"; @import "base/forms"; -@import "base/fonts"; @import "base/grid"; @import "base/font_awesome"; diff --git a/public/sass/base/_fonts.scss b/public/sass/base/_fonts.scss index e442cbdce6c..fb339bc60cf 100644 --- a/public/sass/base/_fonts.scss +++ b/public/sass/base/_fonts.scss @@ -1,185 +1,280 @@ +/* cyrillic-ext */ @font-face { - font-family: 'grafana-icons'; - src: url('../fonts/grafana-icons.eot?h6rv8b'); - src: url('../fonts/grafana-icons.eot?h6rv8b#iefix') format('embedded-opentype'), - url('../fonts/grafana-icons.ttf?h6rv8b') format('truetype'), - url('../fonts/grafana-icons.woff?h6rv8b') format('woff'), - url('../fonts/grafana-icons.svg?h6rv8b#grafana-icons') format('svg'); - font-weight: normal; - font-style: normal; + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } - -.icon-gf { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'grafana-icons' !important; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } - -.inline-icon-gf { - vertical-align: middle; +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } - -.icon-gf-raintank_wordmark:before { - content: "\e600"; +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2) format('woff2'); + unicode-range: U+0370-03FF; } -.icon-gf-raintank_icn:before { - content: "\e601"; +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } -.icon-gf-raintank_r-icn:before { - content: "\e905"; +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } -.icon-gf-check-alt:before { - content: "\e603"; +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } -.icon-gf-check:before { - content: "\e604"; +/* cyrillic-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } -.icon-gf-collector:before { - content: "\e605"; +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } -.icon-gf-dashboard:before { - content: "\e606"; +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/LWCjsQkB6EMdfHrEVqA1KRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } -.icon-gf-panel:before { - content: "\e904"; +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0370-03FF; } -.icon-gf-datasources:before { - content: "\e607"; +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } -.icon-gf-endpoint-tiny:before { - content: "\e608"; +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } -.icon-gf-endpoint:before { - content: "\e609"; +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } -.icon-gf-filter:before { - content: "\e60a"; +/* cyrillic-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } -.icon-gf-status:before { - content: "\e60b"; +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } -.icon-gf-monitoring:before { - content: "\e60c"; +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } -.icon-gf-monitoring-tiny:before { - content: "\e620"; +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2) format('woff2'); + unicode-range: U+0370-03FF; } -.icon-gf-jump-to-dashboard:before { - content: "\e60d"; +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSv8zf_FOSsgRmwsS7Aa9k2w.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } -.icon-gf-warn:before { - content: "\e60e"; +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSj0LW-43aMEzIO6XUTLjad8.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } -.icon-gf-nodata:before { - content: "\e60f"; +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } -.icon-gf-critical:before { - content: "\e610"; +/* cyrillic-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } -.icon-gf-online:before { - content: "\e611"; +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } -.icon-gf-event-error:before { - content: "\e623"; +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } -.icon-gf-event:before { - content: "\e624"; +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2) format('woff2'); + unicode-range: U+0370-03FF; } -.icon-gf-sadface:before { - content: "\e907"; +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } -.icon-gf-private-collector:before { - content: "\e612"; +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } -.icon-gf-alert:before { - content: "\e61f"; +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } -.icon-gf-alert-disabled:before { - content: "\e621"; +/* cyrillic-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } -.icon-gf-refresh:before { - content: "\e613"; +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } -.icon-gf-save:before { - content: "\e614"; +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } -.icon-gf-settings:before { - content: "\e615"; +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2) format('woff2'); + unicode-range: U+0370-03FF; } -.icon-gf-share:before { - content: "\e616"; +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } -.icon-gf-star:before { - content: "\e617"; +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } -.icon-gf-search:before { - content: "\e618"; -} -.icon-gf-tag-add:before { - content: "\e619"; -} -.icon-gf-tag-remove:before { - content: "\e61a"; -} -.icon-gf-video:before { - content: "\e61b"; -} -.icon-gf-bulk_action:before { - content: "\e61c"; -} -.icon-gf-users:before { - content: "\e622"; -} -.icon-gf-globe:before { - content: "\e61d"; -} -.icon-gf-snapshot:before { - content: "\e61e"; -} -.icon-gf-play-grafana-icon:before { - content: "\e629"; -} -.icon-gf-grafana-icon:before { - content: "\e625"; -} -.icon-gf-email:before { - content: "\e628"; -} -.icon-gf-stopwatch:before { - content: "\e626"; -} -.icon-gf-skull:before { - content: "\e900"; -} -.icon-gf-probe:before { - content: "\e901"; -} -.icon-gf-apps:before { - content: "\e902"; -} -.icon-gf-scale:before { - content: "\e906"; -} -.icon-gf-litmus:before { - content: "\e627"; -} -.icon-gf-grafana_wordmark:before { - content: "\e903"; -} - -.icon-gf-app:before { - content: "\e902"; -} -.icon-gf-datasource:before { - content: "\e607"; -} - +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; +} \ No newline at end of file diff --git a/public/sass/base/_grafana_icons.scss b/public/sass/base/_grafana_icons.scss new file mode 100644 index 00000000000..e442cbdce6c --- /dev/null +++ b/public/sass/base/_grafana_icons.scss @@ -0,0 +1,185 @@ +@font-face { + font-family: 'grafana-icons'; + src: url('../fonts/grafana-icons.eot?h6rv8b'); + src: url('../fonts/grafana-icons.eot?h6rv8b#iefix') format('embedded-opentype'), + url('../fonts/grafana-icons.ttf?h6rv8b') format('truetype'), + url('../fonts/grafana-icons.woff?h6rv8b') format('woff'), + url('../fonts/grafana-icons.svg?h6rv8b#grafana-icons') format('svg'); + font-weight: normal; + font-style: normal; +} + +.icon-gf { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'grafana-icons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.inline-icon-gf { + vertical-align: middle; +} + +.icon-gf-raintank_wordmark:before { + content: "\e600"; +} +.icon-gf-raintank_icn:before { + content: "\e601"; +} +.icon-gf-raintank_r-icn:before { + content: "\e905"; +} +.icon-gf-check-alt:before { + content: "\e603"; +} +.icon-gf-check:before { + content: "\e604"; +} +.icon-gf-collector:before { + content: "\e605"; +} +.icon-gf-dashboard:before { + content: "\e606"; +} +.icon-gf-panel:before { + content: "\e904"; +} +.icon-gf-datasources:before { + content: "\e607"; +} +.icon-gf-endpoint-tiny:before { + content: "\e608"; +} +.icon-gf-endpoint:before { + content: "\e609"; +} +.icon-gf-filter:before { + content: "\e60a"; +} +.icon-gf-status:before { + content: "\e60b"; +} +.icon-gf-monitoring:before { + content: "\e60c"; +} +.icon-gf-monitoring-tiny:before { + content: "\e620"; +} +.icon-gf-jump-to-dashboard:before { + content: "\e60d"; +} +.icon-gf-warn:before { + content: "\e60e"; +} +.icon-gf-nodata:before { + content: "\e60f"; +} +.icon-gf-critical:before { + content: "\e610"; +} +.icon-gf-online:before { + content: "\e611"; +} +.icon-gf-event-error:before { + content: "\e623"; +} +.icon-gf-event:before { + content: "\e624"; +} +.icon-gf-sadface:before { + content: "\e907"; +} +.icon-gf-private-collector:before { + content: "\e612"; +} +.icon-gf-alert:before { + content: "\e61f"; +} +.icon-gf-alert-disabled:before { + content: "\e621"; +} +.icon-gf-refresh:before { + content: "\e613"; +} +.icon-gf-save:before { + content: "\e614"; +} +.icon-gf-settings:before { + content: "\e615"; +} +.icon-gf-share:before { + content: "\e616"; +} +.icon-gf-star:before { + content: "\e617"; +} +.icon-gf-search:before { + content: "\e618"; +} +.icon-gf-tag-add:before { + content: "\e619"; +} +.icon-gf-tag-remove:before { + content: "\e61a"; +} +.icon-gf-video:before { + content: "\e61b"; +} +.icon-gf-bulk_action:before { + content: "\e61c"; +} +.icon-gf-users:before { + content: "\e622"; +} +.icon-gf-globe:before { + content: "\e61d"; +} +.icon-gf-snapshot:before { + content: "\e61e"; +} +.icon-gf-play-grafana-icon:before { + content: "\e629"; +} +.icon-gf-grafana-icon:before { + content: "\e625"; +} +.icon-gf-email:before { + content: "\e628"; +} +.icon-gf-stopwatch:before { + content: "\e626"; +} +.icon-gf-skull:before { + content: "\e900"; +} +.icon-gf-probe:before { + content: "\e901"; +} +.icon-gf-apps:before { + content: "\e902"; +} +.icon-gf-scale:before { + content: "\e906"; +} +.icon-gf-litmus:before { + content: "\e627"; +} +.icon-gf-grafana_wordmark:before { + content: "\e903"; +} + +.icon-gf-app:before { + content: "\e902"; +} +.icon-gf-datasource:before { + content: "\e607"; +} + diff --git a/public/sass/fonts.scss b/public/sass/fonts.scss new file mode 100644 index 00000000000..c45e63111c3 --- /dev/null +++ b/public/sass/fonts.scss @@ -0,0 +1,3 @@ +@import "base/fonts"; +@import "base/font_awesome"; +@import "base/grafana_icons"; diff --git a/public/views/index.html b/public/views/index.html index 3208c5ae9ff..49bfe2c5bb9 100644 --- a/public/views/index.html +++ b/public/views/index.html @@ -8,7 +8,7 @@ Grafana - + [[if .User.LightTheme]] diff --git a/tasks/default_task.js b/tasks/default_task.js index 4ce68409c45..d2bebb89789 100644 --- a/tasks/default_task.js +++ b/tasks/default_task.js @@ -6,6 +6,7 @@ module.exports = function(grunt) { 'sass', 'concat:cssDark', 'concat:cssLight', + 'concat:cssFonts', 'styleguide', 'sasslint', 'postcss' diff --git a/tasks/options/concat.js b/tasks/options/concat.js index 59042fc26b0..a5e0753b0cd 100644 --- a/tasks/options/concat.js +++ b/tasks/options/concat.js @@ -22,6 +22,11 @@ module.exports = function(config) { dest: '<%= genDir %>/css/grafana.light.min.css' }, + cssFonts: { + src: [ '<%= genDir %>/css/fonts.css' ], + dest: '<%= genDir %>/css/fonts.min.css' + }, + js: { src: [ '<%= genDir %>/vendor/npm/es5-shim/es5-shim.js', diff --git a/tasks/options/sass.js b/tasks/options/sass.js index f96970740a0..baec4cd861d 100644 --- a/tasks/options/sass.js +++ b/tasks/options/sass.js @@ -6,6 +6,7 @@ module.exports = function(config) { files: { "<%= genDir %>/css/grafana.dark.css": "<%= srcDir %>/sass/grafana.dark.scss", "<%= genDir %>/css/grafana.light.css": "<%= srcDir %>/sass/grafana.light.scss", + "<%= genDir %>/css/fonts.css": "<%= srcDir %>/sass/fonts.scss", } } }; From ed1864e076a0d64b1ad0c09a9a87d9dcc4c056a9 Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 16 Mar 2016 11:52:25 +0100 Subject: [PATCH 30/33] feat(dashlist): stores recently visited dashboards per orgid --- public/app/features/dashboard/impression_store.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/public/app/features/dashboard/impression_store.ts b/public/app/features/dashboard/impression_store.ts index 4bd979a6b34..a0f20f7ec75 100644 --- a/public/app/features/dashboard/impression_store.ts +++ b/public/app/features/dashboard/impression_store.ts @@ -2,14 +2,16 @@ import store from 'app/core/store'; import _ from 'lodash'; +import config from 'app/core/config'; export class ImpressionsStore { constructor() {} addDashboardImpression(dashboardId) { + var impressionsKey = this.impressionKey(config); var impressions = []; - if (store.exists("dashboard_impressions")) { - impressions = JSON.parse(store.get("dashboard_impressions")); + if (store.exists(impressionsKey)) { + impressions = JSON.parse(store.get(impressionsKey)); if (!_.isArray(impressions)) { impressions = []; } @@ -24,11 +26,11 @@ export class ImpressionsStore { if (impressions.length > 50) { impressions.pop(); } - store.set("dashboard_impressions", JSON.stringify(impressions)); + store.set(impressionsKey, JSON.stringify(impressions)); } getDashboardOpened() { - var impressions = store.get("dashboard_impressions") || "[]"; + var impressions = store.get(this.impressionKey(config)) || "[]"; impressions = JSON.parse(impressions); @@ -38,6 +40,10 @@ export class ImpressionsStore { return impressions; } + + impressionKey(config) { + return "dashboard_impressions-" + config.bootData.user.orgId; + } } var impressions = new ImpressionsStore(); From 3486bf92eb998d58d7241add4215e5e5b8f5667a Mon Sep 17 00:00:00 2001 From: Bruno Binet Date: Wed, 16 Mar 2016 11:56:19 +0100 Subject: [PATCH 31/33] [docs] typos --- docs/sources/plugins/installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/plugins/installation.md b/docs/sources/plugins/installation.md index b6db0e82b2c..d3a8013ce2b 100644 --- a/docs/sources/plugins/installation.md +++ b/docs/sources/plugins/installation.md @@ -8,16 +8,16 @@ page_keywords: grafana, plugins, documentation ## Installing plugins -The easiest way to install plugins is by using the CLI tool grafana-cli which is bundled with grafana. Before any modification take place after modifieng plugins, grafana-server need to be restarted. +The easiest way to install plugins is by using the CLI tool grafana-cli which is bundled with grafana. Before any modification take place after modifying plugins, grafana-server needs to be restarted. ### Grafana plugin directory -On Linux systems the grafana-cli will assume that the grafana plugin directory is "/var/lib/grafana/plugins". Its possible to override the directory which grafana-cli will operate on by specifing the --path flag. On Windows systems this parameter have to be specified for every call. +On Linux systems the grafana-cli will assume that the grafana plugin directory is "/var/lib/grafana/plugins". It's possible to override the directory which grafana-cli will operate on by specifing the --path flag. On Windows systems this parameter have to be specified for every call. ### Grafana-cli commands List available plugins ``` -grafana-cli list-remove +grafana-cli list-remote ``` Install a plugin type From a9cdf580a74464a0d44b09b077b4470ddccf1902 Mon Sep 17 00:00:00 2001 From: Vitor Boschi Date: Wed, 16 Mar 2016 09:06:44 -0300 Subject: [PATCH 32/33] fix typo --- public/app/core/utils/kbn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/core/utils/kbn.js b/public/app/core/utils/kbn.js index f6e4277523e..11a544d2708 100644 --- a/public/app/core/utils/kbn.js +++ b/public/app/core/utils/kbn.js @@ -171,7 +171,7 @@ function($, _) { kbn.describe_interval = function (string) { var matches = string.match(kbn.interval_regex); if (!matches || !_.has(kbn.intervals_in_seconds, matches[2])) { - throw new Error('Invalid interval string, expexcting a number followed by one of "Mwdhmsy"'); + throw new Error('Invalid interval string, expecting a number followed by one of "Mwdhmsy"'); } else { return { sec: kbn.intervals_in_seconds[matches[2]], From d26d7162a5dfe0dc4d6808dea031f75918a3e56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 16 Mar 2016 13:10:48 +0100 Subject: [PATCH 33/33] fix(opentsdb): fixed templating issue for single value variables, fixes #4312 --- public/app/features/templating/templateSrv.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/app/features/templating/templateSrv.js b/public/app/features/templating/templateSrv.js index ece69302196..0aa0990896c 100644 --- a/public/app/features/templating/templateSrv.js +++ b/public/app/features/templating/templateSrv.js @@ -69,6 +69,9 @@ function (angular, _) { return '(' + quotedValues.join(' OR ') + ')'; } case "pipe": { + if (typeof value === 'string') { + return value; + } return value.join('|'); } default: {