diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca8d1e413..ab32a3683d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ 1. [#3214](https://github.com/influxdata/chronograf/pull/3214): Remove extra click when creating dashboard cell 1. [#3256](https://github.com/influxdata/chronograf/pull/3256): Reduce font sizes in dashboards for increased space efficiency 1. [#3320](https://github.com/influxdata/chronograf/pull/3320): Add overlay animation to Template Variables Manager +1. [#3245](https://github.com/influxdata/chronograf/pull/3245): Display 'no results' on cells without results ### Bug Fixes diff --git a/bolt/change_interval_to_duration.go b/bolt/change_interval_to_duration.go index 1ab06be3a0..d2801b32fe 100644 --- a/bolt/change_interval_to_duration.go +++ b/bolt/change_interval_to_duration.go @@ -344,7 +344,6 @@ func (m *DashboardCell) GetTableOptions() *TableOptions { } type TableOptions struct { - TimeFormat string `protobuf:"bytes,1,opt,name=timeFormat,proto3" json:"timeFormat,omitempty"` VerticalTimeAxis bool `protobuf:"varint,2,opt,name=verticalTimeAxis,proto3" json:"verticalTimeAxis,omitempty"` SortBy *RenamableField `protobuf:"bytes,3,opt,name=sortBy" json:"sortBy,omitempty"` Wrapping string `protobuf:"bytes,4,opt,name=wrapping,proto3" json:"wrapping,omitempty"` @@ -357,13 +356,6 @@ func (m *TableOptions) String() string { return proto.CompactTextStri func (*TableOptions) ProtoMessage() {} func (*TableOptions) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{3} } -func (m *TableOptions) GetTimeFormat() string { - if m != nil { - return m.TimeFormat - } - return "" -} - func (m *TableOptions) GetVerticalTimeAxis() bool { if m != nil { return m.VerticalTimeAxis diff --git a/bolt/internal/internal.go b/bolt/internal/internal.go index 78c8e28644..8b7fe2e6e6 100644 --- a/bolt/internal/internal.go +++ b/bolt/internal/internal.go @@ -273,24 +273,27 @@ func MarshalDashboard(d chronograf.Dashboard) ([]byte, error) { Visible: c.TableOptions.SortBy.Visible, } - fieldNames := make([]*RenamableField, len(c.TableOptions.FieldNames)) - for i, field := range c.TableOptions.FieldNames { - fieldNames[i] = &RenamableField{ + tableOptions := &TableOptions{ + VerticalTimeAxis: c.TableOptions.VerticalTimeAxis, + SortBy: sortBy, + Wrapping: c.TableOptions.Wrapping, + FixFirstColumn: c.TableOptions.FixFirstColumn, + } + + decimalPlaces := &DecimalPlaces{ + IsEnforced: c.DecimalPlaces.IsEnforced, + Digits: c.DecimalPlaces.Digits, + } + + fieldOptions := make([]*RenamableField, len(c.FieldOptions)) + for i, field := range c.FieldOptions { + fieldOptions[i] = &RenamableField{ InternalName: field.InternalName, DisplayName: field.DisplayName, Visible: field.Visible, } } - tableOptions := &TableOptions{ - TimeFormat: c.TableOptions.TimeFormat, - VerticalTimeAxis: c.TableOptions.VerticalTimeAxis, - SortBy: sortBy, - Wrapping: c.TableOptions.Wrapping, - FieldNames: fieldNames, - FixFirstColumn: c.TableOptions.FixFirstColumn, - } - cells[i] = &DashboardCell{ ID: c.ID, X: c.X, @@ -306,7 +309,10 @@ func MarshalDashboard(d chronograf.Dashboard) ([]byte, error) { Type: c.Legend.Type, Orientation: c.Legend.Orientation, }, - TableOptions: tableOptions, + TableOptions: tableOptions, + FieldOptions: fieldOptions, + TimeFormat: c.TimeFormat, + DecimalPlaces: decimalPlaces, } } templates := make([]*Template, len(d.Templates)) @@ -442,20 +448,26 @@ func UnmarshalDashboard(data []byte, d *chronograf.Dashboard) error { sortBy.Visible = c.TableOptions.SortBy.Visible } tableOptions.SortBy = sortBy - - fieldNames := make([]chronograf.RenamableField, len(c.TableOptions.FieldNames)) - for i, field := range c.TableOptions.FieldNames { - fieldNames[i] = chronograf.RenamableField{} - fieldNames[i].InternalName = field.InternalName - fieldNames[i].DisplayName = field.DisplayName - fieldNames[i].Visible = field.Visible - } - tableOptions.FieldNames = fieldNames - tableOptions.TimeFormat = c.TableOptions.TimeFormat tableOptions.VerticalTimeAxis = c.TableOptions.VerticalTimeAxis tableOptions.Wrapping = c.TableOptions.Wrapping tableOptions.FixFirstColumn = c.TableOptions.FixFirstColumn + } + fieldOptions := make([]chronograf.RenamableField, len(c.FieldOptions)) + for i, field := range c.FieldOptions { + fieldOptions[i] = chronograf.RenamableField{} + fieldOptions[i].InternalName = field.InternalName + fieldOptions[i].DisplayName = field.DisplayName + fieldOptions[i].Visible = field.Visible + } + + decimalPlaces := chronograf.DecimalPlaces{} + if c.DecimalPlaces != nil { + decimalPlaces.IsEnforced = c.DecimalPlaces.IsEnforced + decimalPlaces.Digits = c.DecimalPlaces.Digits + } else { + decimalPlaces.IsEnforced = false + decimalPlaces.Digits = 3 } // FIXME: this is merely for legacy cells and @@ -466,18 +478,21 @@ func UnmarshalDashboard(data []byte, d *chronograf.Dashboard) error { } cells[i] = chronograf.DashboardCell{ - ID: c.ID, - X: c.X, - Y: c.Y, - W: c.W, - H: c.H, - Name: c.Name, - Queries: queries, - Type: cellType, - Axes: axes, - CellColors: colors, - Legend: legend, - TableOptions: tableOptions, + ID: c.ID, + X: c.X, + Y: c.Y, + W: c.W, + H: c.H, + Name: c.Name, + Queries: queries, + Type: cellType, + Axes: axes, + CellColors: colors, + Legend: legend, + TableOptions: tableOptions, + FieldOptions: fieldOptions, + TimeFormat: c.TimeFormat, + DecimalPlaces: decimalPlaces, } } diff --git a/bolt/internal/internal.pb.go b/bolt/internal/internal.pb.go index f805b26e95..48177f7e10 100644 --- a/bolt/internal/internal.pb.go +++ b/bolt/internal/internal.pb.go @@ -11,6 +11,7 @@ It has these top-level messages: Source Dashboard DashboardCell + DecimalPlaces TableOptions RenamableField Color @@ -220,18 +221,21 @@ func (m *Dashboard) GetOrganization() string { } type DashboardCell struct { - X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` - W int32 `protobuf:"varint,3,opt,name=w,proto3" json:"w,omitempty"` - H int32 `protobuf:"varint,4,opt,name=h,proto3" json:"h,omitempty"` - Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` - Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"` - ID string `protobuf:"bytes,8,opt,name=ID,proto3" json:"ID,omitempty"` - Axes map[string]*Axis `protobuf:"bytes,9,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"` - Colors []*Color `protobuf:"bytes,10,rep,name=colors" json:"colors,omitempty"` - Legend *Legend `protobuf:"bytes,11,opt,name=legend" json:"legend,omitempty"` - TableOptions *TableOptions `protobuf:"bytes,12,opt,name=tableOptions" json:"tableOptions,omitempty"` + X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` + Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` + W int32 `protobuf:"varint,3,opt,name=w,proto3" json:"w,omitempty"` + H int32 `protobuf:"varint,4,opt,name=h,proto3" json:"h,omitempty"` + Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"` + ID string `protobuf:"bytes,8,opt,name=ID,proto3" json:"ID,omitempty"` + Axes map[string]*Axis `protobuf:"bytes,9,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"` + Colors []*Color `protobuf:"bytes,10,rep,name=colors" json:"colors,omitempty"` + Legend *Legend `protobuf:"bytes,11,opt,name=legend" json:"legend,omitempty"` + TableOptions *TableOptions `protobuf:"bytes,12,opt,name=tableOptions" json:"tableOptions,omitempty"` + FieldOptions []*RenamableField `protobuf:"bytes,13,rep,name=fieldOptions" json:"fieldOptions,omitempty"` + TimeFormat string `protobuf:"bytes,14,opt,name=timeFormat,proto3" json:"timeFormat,omitempty"` + DecimalPlaces *DecimalPlaces `protobuf:"bytes,15,opt,name=decimalPlaces" json:"decimalPlaces,omitempty"` } func (m *DashboardCell) Reset() { *m = DashboardCell{} } @@ -323,27 +327,63 @@ func (m *DashboardCell) GetTableOptions() *TableOptions { return nil } -type TableOptions struct { - TimeFormat string `protobuf:"bytes,1,opt,name=timeFormat,proto3" json:"timeFormat,omitempty"` - VerticalTimeAxis bool `protobuf:"varint,2,opt,name=verticalTimeAxis,proto3" json:"verticalTimeAxis,omitempty"` - SortBy *RenamableField `protobuf:"bytes,3,opt,name=sortBy" json:"sortBy,omitempty"` - Wrapping string `protobuf:"bytes,4,opt,name=wrapping,proto3" json:"wrapping,omitempty"` - FieldNames []*RenamableField `protobuf:"bytes,5,rep,name=fieldNames" json:"fieldNames,omitempty"` - FixFirstColumn bool `protobuf:"varint,6,opt,name=fixFirstColumn,proto3" json:"fixFirstColumn,omitempty"` +func (m *DashboardCell) GetFieldOptions() []*RenamableField { + if m != nil { + return m.FieldOptions + } + return nil } -func (m *TableOptions) Reset() { *m = TableOptions{} } -func (m *TableOptions) String() string { return proto.CompactTextString(m) } -func (*TableOptions) ProtoMessage() {} -func (*TableOptions) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{3} } - -func (m *TableOptions) GetTimeFormat() string { +func (m *DashboardCell) GetTimeFormat() string { if m != nil { return m.TimeFormat } return "" } +func (m *DashboardCell) GetDecimalPlaces() *DecimalPlaces { + if m != nil { + return m.DecimalPlaces + } + return nil +} + +type DecimalPlaces struct { + IsEnforced bool `protobuf:"varint,1,opt,name=isEnforced,proto3" json:"isEnforced,omitempty"` + Digits int32 `protobuf:"varint,2,opt,name=digits,proto3" json:"digits,omitempty"` +} + +func (m *DecimalPlaces) Reset() { *m = DecimalPlaces{} } +func (m *DecimalPlaces) String() string { return proto.CompactTextString(m) } +func (*DecimalPlaces) ProtoMessage() {} +func (*DecimalPlaces) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{3} } + +func (m *DecimalPlaces) GetIsEnforced() bool { + if m != nil { + return m.IsEnforced + } + return false +} + +func (m *DecimalPlaces) GetDigits() int32 { + if m != nil { + return m.Digits + } + return 0 +} + +type TableOptions struct { + VerticalTimeAxis bool `protobuf:"varint,2,opt,name=verticalTimeAxis,proto3" json:"verticalTimeAxis,omitempty"` + SortBy *RenamableField `protobuf:"bytes,3,opt,name=sortBy" json:"sortBy,omitempty"` + Wrapping string `protobuf:"bytes,4,opt,name=wrapping,proto3" json:"wrapping,omitempty"` + FixFirstColumn bool `protobuf:"varint,6,opt,name=fixFirstColumn,proto3" json:"fixFirstColumn,omitempty"` +} + +func (m *TableOptions) Reset() { *m = TableOptions{} } +func (m *TableOptions) String() string { return proto.CompactTextString(m) } +func (*TableOptions) ProtoMessage() {} +func (*TableOptions) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{4} } + func (m *TableOptions) GetVerticalTimeAxis() bool { if m != nil { return m.VerticalTimeAxis @@ -365,13 +405,6 @@ func (m *TableOptions) GetWrapping() string { return "" } -func (m *TableOptions) GetFieldNames() []*RenamableField { - if m != nil { - return m.FieldNames - } - return nil -} - func (m *TableOptions) GetFixFirstColumn() bool { if m != nil { return m.FixFirstColumn @@ -388,7 +421,7 @@ type RenamableField struct { func (m *RenamableField) Reset() { *m = RenamableField{} } func (m *RenamableField) String() string { return proto.CompactTextString(m) } func (*RenamableField) ProtoMessage() {} -func (*RenamableField) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{4} } +func (*RenamableField) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{5} } func (m *RenamableField) GetInternalName() string { if m != nil { @@ -422,7 +455,7 @@ type Color struct { func (m *Color) Reset() { *m = Color{} } func (m *Color) String() string { return proto.CompactTextString(m) } func (*Color) ProtoMessage() {} -func (*Color) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{5} } +func (*Color) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{6} } func (m *Color) GetID() string { if m != nil { @@ -467,7 +500,7 @@ type Legend struct { func (m *Legend) Reset() { *m = Legend{} } func (m *Legend) String() string { return proto.CompactTextString(m) } func (*Legend) ProtoMessage() {} -func (*Legend) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{6} } +func (*Legend) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{7} } func (m *Legend) GetType() string { if m != nil { @@ -496,7 +529,7 @@ type Axis struct { func (m *Axis) Reset() { *m = Axis{} } func (m *Axis) String() string { return proto.CompactTextString(m) } func (*Axis) ProtoMessage() {} -func (*Axis) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{7} } +func (*Axis) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{8} } func (m *Axis) GetLegacyBounds() []int64 { if m != nil { @@ -559,7 +592,7 @@ type Template struct { func (m *Template) Reset() { *m = Template{} } func (m *Template) String() string { return proto.CompactTextString(m) } func (*Template) ProtoMessage() {} -func (*Template) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{8} } +func (*Template) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{9} } func (m *Template) GetID() string { if m != nil { @@ -612,7 +645,7 @@ type TemplateValue struct { func (m *TemplateValue) Reset() { *m = TemplateValue{} } func (m *TemplateValue) String() string { return proto.CompactTextString(m) } func (*TemplateValue) ProtoMessage() {} -func (*TemplateValue) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{9} } +func (*TemplateValue) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{10} } func (m *TemplateValue) GetType() string { if m != nil { @@ -647,7 +680,7 @@ type TemplateQuery struct { func (m *TemplateQuery) Reset() { *m = TemplateQuery{} } func (m *TemplateQuery) String() string { return proto.CompactTextString(m) } func (*TemplateQuery) ProtoMessage() {} -func (*TemplateQuery) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{10} } +func (*TemplateQuery) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{11} } func (m *TemplateQuery) GetCommand() string { if m != nil { @@ -706,7 +739,7 @@ type Server struct { func (m *Server) Reset() { *m = Server{} } func (m *Server) String() string { return proto.CompactTextString(m) } func (*Server) ProtoMessage() {} -func (*Server) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{11} } +func (*Server) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{12} } func (m *Server) GetID() int64 { if m != nil { @@ -782,7 +815,7 @@ type Layout struct { func (m *Layout) Reset() { *m = Layout{} } func (m *Layout) String() string { return proto.CompactTextString(m) } func (*Layout) ProtoMessage() {} -func (*Layout) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{12} } +func (*Layout) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{13} } func (m *Layout) GetID() string { if m != nil { @@ -836,7 +869,7 @@ type Cell struct { func (m *Cell) Reset() { *m = Cell{} } func (m *Cell) String() string { return proto.CompactTextString(m) } func (*Cell) ProtoMessage() {} -func (*Cell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{13} } +func (*Cell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{14} } func (m *Cell) GetX() int32 { if m != nil { @@ -930,7 +963,7 @@ type Query struct { func (m *Query) Reset() { *m = Query{} } func (m *Query) String() string { return proto.CompactTextString(m) } func (*Query) ProtoMessage() {} -func (*Query) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{14} } +func (*Query) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{15} } func (m *Query) GetCommand() string { if m != nil { @@ -1004,7 +1037,7 @@ type TimeShift struct { func (m *TimeShift) Reset() { *m = TimeShift{} } func (m *TimeShift) String() string { return proto.CompactTextString(m) } func (*TimeShift) ProtoMessage() {} -func (*TimeShift) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{15} } +func (*TimeShift) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{16} } func (m *TimeShift) GetLabel() string { if m != nil { @@ -1035,7 +1068,7 @@ type Range struct { func (m *Range) Reset() { *m = Range{} } func (m *Range) String() string { return proto.CompactTextString(m) } func (*Range) ProtoMessage() {} -func (*Range) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{16} } +func (*Range) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{17} } func (m *Range) GetUpper() int64 { if m != nil { @@ -1061,7 +1094,7 @@ type AlertRule struct { func (m *AlertRule) Reset() { *m = AlertRule{} } func (m *AlertRule) String() string { return proto.CompactTextString(m) } func (*AlertRule) ProtoMessage() {} -func (*AlertRule) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{17} } +func (*AlertRule) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{18} } func (m *AlertRule) GetID() string { if m != nil { @@ -1103,7 +1136,7 @@ type User struct { func (m *User) Reset() { *m = User{} } func (m *User) String() string { return proto.CompactTextString(m) } func (*User) ProtoMessage() {} -func (*User) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{18} } +func (*User) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{19} } func (m *User) GetID() uint64 { if m != nil { @@ -1155,7 +1188,7 @@ type Role struct { func (m *Role) Reset() { *m = Role{} } func (m *Role) String() string { return proto.CompactTextString(m) } func (*Role) ProtoMessage() {} -func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{19} } +func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{20} } func (m *Role) GetOrganization() string { if m != nil { @@ -1182,7 +1215,7 @@ type Mapping struct { func (m *Mapping) Reset() { *m = Mapping{} } func (m *Mapping) String() string { return proto.CompactTextString(m) } func (*Mapping) ProtoMessage() {} -func (*Mapping) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{20} } +func (*Mapping) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{21} } func (m *Mapping) GetProvider() string { if m != nil { @@ -1228,7 +1261,7 @@ type Organization struct { func (m *Organization) Reset() { *m = Organization{} } func (m *Organization) String() string { return proto.CompactTextString(m) } func (*Organization) ProtoMessage() {} -func (*Organization) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{21} } +func (*Organization) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{22} } func (m *Organization) GetID() string { if m != nil { @@ -1258,7 +1291,7 @@ type Config struct { func (m *Config) Reset() { *m = Config{} } func (m *Config) String() string { return proto.CompactTextString(m) } func (*Config) ProtoMessage() {} -func (*Config) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{22} } +func (*Config) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{23} } func (m *Config) GetAuth() *AuthConfig { if m != nil { @@ -1274,7 +1307,7 @@ type AuthConfig struct { func (m *AuthConfig) Reset() { *m = AuthConfig{} } func (m *AuthConfig) String() string { return proto.CompactTextString(m) } func (*AuthConfig) ProtoMessage() {} -func (*AuthConfig) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{23} } +func (*AuthConfig) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{24} } func (m *AuthConfig) GetSuperAdminNewUsers() bool { if m != nil { @@ -1291,7 +1324,7 @@ type BuildInfo struct { func (m *BuildInfo) Reset() { *m = BuildInfo{} } func (m *BuildInfo) String() string { return proto.CompactTextString(m) } func (*BuildInfo) ProtoMessage() {} -func (*BuildInfo) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{24} } +func (*BuildInfo) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{25} } func (m *BuildInfo) GetVersion() string { if m != nil { @@ -1311,6 +1344,7 @@ func init() { proto.RegisterType((*Source)(nil), "internal.Source") proto.RegisterType((*Dashboard)(nil), "internal.Dashboard") proto.RegisterType((*DashboardCell)(nil), "internal.DashboardCell") + proto.RegisterType((*DecimalPlaces)(nil), "internal.DecimalPlaces") proto.RegisterType((*TableOptions)(nil), "internal.TableOptions") proto.RegisterType((*RenamableField)(nil), "internal.RenamableField") proto.RegisterType((*Color)(nil), "internal.Color") @@ -1338,105 +1372,110 @@ func init() { func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) } var fileDescriptorInternal = []byte{ - // 1599 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0xdb, 0xc8, - 0x15, 0x07, 0x45, 0x51, 0x12, 0x9f, 0x1c, 0xd7, 0x98, 0x1a, 0x09, 0x9b, 0x16, 0x85, 0x4a, 0xf4, - 0x43, 0xfd, 0x88, 0x1b, 0x28, 0x28, 0x10, 0x04, 0x6d, 0x00, 0xd9, 0x6a, 0x52, 0x37, 0x4e, 0xec, - 0x8c, 0x6c, 0xf7, 0x54, 0x04, 0x23, 0x69, 0x24, 0x11, 0xa1, 0x48, 0x76, 0x48, 0xda, 0x62, 0xcf, - 0x3d, 0xf5, 0x8f, 0x28, 0x50, 0xa0, 0xfd, 0x07, 0x8a, 0x5e, 0xf6, 0xb4, 0xf7, 0xfd, 0x87, 0x76, - 0x8f, 0x8b, 0x37, 0x1f, 0x24, 0x65, 0x29, 0x41, 0x16, 0x58, 0xec, 0x6d, 0x7e, 0xef, 0x3d, 0xbd, - 0x99, 0xf7, 0xfd, 0x28, 0xd8, 0x0f, 0xa2, 0x8c, 0x8b, 0x88, 0x85, 0x47, 0x89, 0x88, 0xb3, 0x98, - 0x74, 0x0c, 0xf6, 0xff, 0x61, 0x43, 0x6b, 0x1c, 0xe7, 0x62, 0xca, 0xc9, 0x3e, 0x34, 0x4e, 0x47, - 0x9e, 0xd5, 0xb3, 0xfa, 0x36, 0x6d, 0x9c, 0x8e, 0x08, 0x81, 0xe6, 0x1b, 0xb6, 0xe2, 0x5e, 0xa3, - 0x67, 0xf5, 0x5d, 0x2a, 0xcf, 0x48, 0xbb, 0x2c, 0x12, 0xee, 0xd9, 0x8a, 0x86, 0x67, 0xf2, 0x10, - 0x3a, 0x57, 0x29, 0x6a, 0x5b, 0x71, 0xaf, 0x29, 0xe9, 0x25, 0x46, 0xde, 0x05, 0x4b, 0xd3, 0xdb, - 0x58, 0xcc, 0x3c, 0x47, 0xf1, 0x0c, 0x26, 0x07, 0x60, 0x5f, 0xd1, 0x33, 0xaf, 0x25, 0xc9, 0x78, - 0x24, 0x1e, 0xb4, 0x47, 0x7c, 0xce, 0xf2, 0x30, 0xf3, 0xda, 0x3d, 0xab, 0xdf, 0xa1, 0x06, 0xa2, - 0x9e, 0x4b, 0x1e, 0xf2, 0x85, 0x60, 0x73, 0xaf, 0xa3, 0xf4, 0x18, 0x4c, 0x8e, 0x80, 0x9c, 0x46, - 0x29, 0x9f, 0xe6, 0x82, 0x8f, 0xdf, 0x07, 0xc9, 0x35, 0x17, 0xc1, 0xbc, 0xf0, 0x5c, 0xa9, 0x60, - 0x07, 0x07, 0x6f, 0x79, 0xcd, 0x33, 0x86, 0x77, 0x83, 0x54, 0x65, 0x20, 0xf1, 0x61, 0x6f, 0xbc, - 0x64, 0x82, 0xcf, 0xc6, 0x7c, 0x2a, 0x78, 0xe6, 0x75, 0x25, 0x7b, 0x83, 0x86, 0x32, 0xe7, 0x62, - 0xc1, 0xa2, 0xe0, 0xef, 0x2c, 0x0b, 0xe2, 0xc8, 0xdb, 0x53, 0x32, 0x75, 0x1a, 0x7a, 0x89, 0xc6, - 0x21, 0xf7, 0xee, 0x29, 0x2f, 0xe1, 0x99, 0xfc, 0x08, 0x5c, 0x6d, 0x0c, 0xbd, 0xf0, 0xf6, 0x25, - 0xa3, 0x22, 0xf8, 0xff, 0xb7, 0xc0, 0x1d, 0xb1, 0x74, 0x39, 0x89, 0x99, 0x98, 0x7d, 0x52, 0x24, - 0x1e, 0x81, 0x33, 0xe5, 0x61, 0x98, 0x7a, 0x76, 0xcf, 0xee, 0x77, 0x07, 0x0f, 0x8e, 0xca, 0x10, - 0x97, 0x7a, 0x4e, 0x78, 0x18, 0x52, 0x25, 0x45, 0x1e, 0x83, 0x9b, 0xf1, 0x55, 0x12, 0xb2, 0x8c, - 0xa7, 0x5e, 0x53, 0xfe, 0x84, 0x54, 0x3f, 0xb9, 0xd4, 0x2c, 0x5a, 0x09, 0x6d, 0x19, 0xea, 0x6c, - 0x1b, 0xea, 0x7f, 0x66, 0xc3, 0xbd, 0x8d, 0xeb, 0xc8, 0x1e, 0x58, 0x6b, 0xf9, 0x72, 0x87, 0x5a, - 0x6b, 0x44, 0x85, 0x7c, 0xb5, 0x43, 0xad, 0x02, 0xd1, 0xad, 0xcc, 0x1c, 0x87, 0x5a, 0xb7, 0x88, - 0x96, 0x32, 0x5f, 0x1c, 0x6a, 0x2d, 0xc9, 0x2f, 0xa1, 0xfd, 0xb7, 0x9c, 0x8b, 0x80, 0xa7, 0x9e, - 0x23, 0x5f, 0xf7, 0xbd, 0xea, 0x75, 0x6f, 0x73, 0x2e, 0x0a, 0x6a, 0xf8, 0xe8, 0x0d, 0x99, 0x6b, - 0x2a, 0x71, 0xe4, 0x19, 0x69, 0x19, 0xe6, 0x65, 0x5b, 0xd1, 0xf0, 0xac, 0xbd, 0xa8, 0xb2, 0x05, - 0xbd, 0xf8, 0x3b, 0x68, 0xb2, 0x35, 0x4f, 0x3d, 0x57, 0xea, 0xff, 0xc9, 0x07, 0x1c, 0x76, 0x34, - 0x5c, 0xf3, 0xf4, 0x8f, 0x51, 0x26, 0x0a, 0x2a, 0xc5, 0xc9, 0x2f, 0xa0, 0x35, 0x8d, 0xc3, 0x58, - 0xa4, 0x1e, 0xdc, 0x7d, 0xd8, 0x09, 0xd2, 0xa9, 0x66, 0x93, 0x3e, 0xb4, 0x42, 0xbe, 0xe0, 0xd1, - 0x4c, 0xe6, 0x4d, 0x77, 0x70, 0x50, 0x09, 0x9e, 0x49, 0x3a, 0xd5, 0x7c, 0xf2, 0x0c, 0xf6, 0x32, - 0x36, 0x09, 0xf9, 0x79, 0x82, 0x5e, 0x4c, 0x65, 0x0e, 0x75, 0x07, 0xf7, 0x6b, 0xf1, 0xa8, 0x71, - 0xe9, 0x86, 0xec, 0xc3, 0x97, 0xe0, 0x96, 0x2f, 0xc4, 0x12, 0x7a, 0xcf, 0x0b, 0xe9, 0x6f, 0x97, - 0xe2, 0x91, 0xfc, 0x14, 0x9c, 0x1b, 0x16, 0xe6, 0x2a, 0x57, 0xba, 0x83, 0xfd, 0x4a, 0xe7, 0x70, - 0x1d, 0xa4, 0x54, 0x31, 0x9f, 0x35, 0x9e, 0x5a, 0xfe, 0x3f, 0x1b, 0xb0, 0x57, 0xbf, 0x87, 0xfc, - 0x18, 0x20, 0x0b, 0x56, 0xfc, 0x45, 0x2c, 0x56, 0x2c, 0xd3, 0x3a, 0x6b, 0x14, 0xf2, 0x2b, 0x38, - 0xb8, 0xe1, 0x22, 0x0b, 0xa6, 0x2c, 0xbc, 0x0c, 0x56, 0x1c, 0xf5, 0xc9, 0x5b, 0x3a, 0x74, 0x8b, - 0x4e, 0x1e, 0x43, 0x2b, 0x8d, 0x45, 0x76, 0x5c, 0xc8, 0x78, 0x77, 0x07, 0x5e, 0xf5, 0x0e, 0xca, - 0x23, 0xb6, 0xc2, 0x7b, 0x5f, 0x04, 0x3c, 0x9c, 0x51, 0x2d, 0x87, 0x15, 0x7e, 0x2b, 0x58, 0x92, - 0x04, 0xd1, 0xc2, 0x74, 0x11, 0x83, 0xc9, 0x53, 0x80, 0x39, 0x0a, 0x63, 0xe2, 0x9b, 0xfc, 0xf8, - 0xb0, 0xc6, 0x9a, 0x2c, 0xf9, 0x39, 0xec, 0xcf, 0x83, 0xf5, 0x8b, 0x40, 0xa4, 0xd9, 0x49, 0x1c, - 0xe6, 0xab, 0x48, 0x66, 0x4d, 0x87, 0xde, 0xa1, 0xfa, 0x09, 0xec, 0x6f, 0x6a, 0xc1, 0xf4, 0x37, - 0x17, 0xc8, 0xda, 0x53, 0xfe, 0xd8, 0xa0, 0x91, 0x1e, 0x74, 0x67, 0x41, 0x9a, 0x84, 0xac, 0xa8, - 0x95, 0x67, 0x9d, 0x84, 0xbd, 0xe6, 0x26, 0x48, 0x83, 0x49, 0xa8, 0x5a, 0x66, 0x87, 0x1a, 0xe8, - 0x2f, 0xc0, 0x91, 0xe9, 0x53, 0x2b, 0x76, 0xd7, 0x14, 0xbb, 0x6c, 0xb1, 0x8d, 0x5a, 0x8b, 0x3d, - 0x00, 0xfb, 0x4f, 0x7c, 0xad, 0xbb, 0x2e, 0x1e, 0xcb, 0x96, 0xd0, 0xac, 0xb5, 0x84, 0x43, 0x70, - 0xae, 0x65, 0xec, 0x55, 0xa9, 0x2a, 0xe0, 0x3f, 0x87, 0x96, 0x4a, 0xbf, 0x52, 0xb3, 0x55, 0xd3, - 0xdc, 0x83, 0xee, 0xb9, 0x08, 0x78, 0x94, 0xa9, 0x22, 0xd7, 0x26, 0xd4, 0x48, 0xfe, 0xff, 0x2c, - 0x68, 0xca, 0x98, 0xfa, 0xb0, 0x17, 0xf2, 0x05, 0x9b, 0x16, 0xc7, 0x71, 0x1e, 0xcd, 0x52, 0xcf, - 0xea, 0xd9, 0x7d, 0x9b, 0x6e, 0xd0, 0xc8, 0x7d, 0x68, 0x4d, 0x14, 0xb7, 0xd1, 0xb3, 0xfb, 0x2e, - 0xd5, 0x08, 0x9f, 0x16, 0xb2, 0x09, 0x0f, 0xb5, 0x09, 0x0a, 0xa0, 0x74, 0x22, 0xf8, 0x3c, 0x58, - 0x6b, 0x33, 0x34, 0x42, 0x7a, 0x9a, 0xcf, 0x91, 0xae, 0x2c, 0xd1, 0x08, 0x0d, 0x98, 0xb0, 0xb4, - 0xac, 0x7c, 0x3c, 0xa3, 0xe6, 0x74, 0xca, 0x42, 0x53, 0xfa, 0x0a, 0xf8, 0x9f, 0x5b, 0x38, 0x30, - 0x54, 0x2b, 0xdb, 0xf2, 0xf0, 0x0f, 0xa0, 0x83, 0x6d, 0xee, 0xdd, 0x0d, 0x13, 0xda, 0xe0, 0x36, - 0xe2, 0x6b, 0x26, 0xc8, 0x6f, 0xa1, 0x25, 0x2b, 0x64, 0x47, 0x5b, 0x35, 0xea, 0xa4, 0x57, 0xa9, - 0x16, 0x2b, 0x1b, 0x4f, 0xb3, 0xd6, 0x78, 0x4a, 0x63, 0x9d, 0xba, 0xb1, 0x8f, 0xc0, 0xc1, 0x0e, - 0x56, 0xc8, 0xd7, 0xef, 0xd4, 0xac, 0xfa, 0x9c, 0x92, 0xf2, 0xaf, 0xe0, 0xde, 0xc6, 0x8d, 0xe5, - 0x4d, 0xd6, 0xe6, 0x4d, 0x55, 0xb5, 0xbb, 0xba, 0xba, 0xb1, 0x94, 0x52, 0x1e, 0xf2, 0x69, 0xc6, - 0x67, 0x3a, 0xeb, 0x4a, 0xec, 0xff, 0xdb, 0xaa, 0xf4, 0xca, 0xfb, 0x30, 0x45, 0xa7, 0xf1, 0x6a, - 0xc5, 0xa2, 0x99, 0x56, 0x6d, 0x20, 0xfa, 0x6d, 0x36, 0xd1, 0xaa, 0x1b, 0xb3, 0x09, 0x62, 0x91, - 0xe8, 0x08, 0x36, 0x44, 0x82, 0xb9, 0xb3, 0xe2, 0x2c, 0xcd, 0x05, 0x5f, 0xf1, 0x28, 0xd3, 0x2e, - 0xa8, 0x93, 0xc8, 0x03, 0x68, 0x67, 0x6c, 0xf1, 0x0e, 0x7b, 0x94, 0x8e, 0x64, 0xc6, 0x16, 0xaf, - 0x78, 0x41, 0x7e, 0x08, 0xae, 0xac, 0x52, 0xc9, 0x52, 0xe1, 0xec, 0x48, 0xc2, 0x2b, 0x5e, 0xf8, - 0x5f, 0x59, 0xd0, 0x1a, 0x73, 0x71, 0xc3, 0xc5, 0x27, 0x4d, 0xc2, 0xfa, 0xfe, 0x61, 0x7f, 0x64, - 0xff, 0x68, 0xee, 0xde, 0x3f, 0x9c, 0x6a, 0xff, 0x38, 0x04, 0x67, 0x2c, 0xa6, 0xa7, 0x23, 0xf9, - 0x22, 0x9b, 0x2a, 0x80, 0xd9, 0x38, 0x9c, 0x66, 0xc1, 0x0d, 0xd7, 0x4b, 0x89, 0x46, 0x5b, 0x03, - 0xb2, 0xb3, 0x63, 0x13, 0xf8, 0x86, 0xbb, 0x89, 0xff, 0x2f, 0x0b, 0x5a, 0x67, 0xac, 0x88, 0xf3, - 0x6c, 0x2b, 0x6b, 0x7b, 0xd0, 0x1d, 0x26, 0x49, 0x18, 0x4c, 0x37, 0x2a, 0xb5, 0x46, 0x42, 0x89, - 0xd7, 0xb5, 0x78, 0x28, 0x5f, 0xd4, 0x49, 0x38, 0x1d, 0x4e, 0xe4, 0xd2, 0xa0, 0x36, 0x80, 0xda, - 0x74, 0x50, 0xbb, 0x82, 0x64, 0xa2, 0xd3, 0x86, 0x79, 0x16, 0xcf, 0xc3, 0xf8, 0x56, 0x7a, 0xa7, - 0x43, 0x4b, 0xec, 0x7f, 0xd1, 0x80, 0xe6, 0x77, 0x35, 0xe8, 0xf7, 0xc0, 0x0a, 0x74, 0x72, 0x58, - 0x41, 0x39, 0xf6, 0xdb, 0xb5, 0xb1, 0xef, 0x41, 0xbb, 0x10, 0x2c, 0x5a, 0xf0, 0xd4, 0xeb, 0xc8, - 0x6e, 0x64, 0xa0, 0xe4, 0xc8, 0xba, 0x53, 0xf3, 0xde, 0xa5, 0x06, 0x96, 0x75, 0x04, 0xb5, 0x3a, - 0xfa, 0x8d, 0x5e, 0x0d, 0xba, 0x77, 0x47, 0xcb, 0xae, 0x8d, 0xe0, 0xdb, 0x1b, 0xc1, 0x5f, 0x5a, - 0xe0, 0x94, 0x45, 0x78, 0xb2, 0x59, 0x84, 0x27, 0x55, 0x11, 0x8e, 0x8e, 0x4d, 0x11, 0x8e, 0x8e, - 0x11, 0xd3, 0x0b, 0x53, 0x84, 0xf4, 0x02, 0x83, 0xf5, 0x52, 0xc4, 0x79, 0x72, 0x5c, 0xa8, 0xa8, - 0xba, 0xb4, 0xc4, 0x98, 0xb9, 0x7f, 0x59, 0x72, 0xa1, 0x5d, 0xed, 0x52, 0x8d, 0x30, 0xcf, 0xcf, - 0x64, 0x83, 0x52, 0xce, 0x55, 0x80, 0xfc, 0x0c, 0x1c, 0x8a, 0xce, 0x93, 0x1e, 0xde, 0x88, 0x8b, - 0x24, 0x53, 0xc5, 0x45, 0xa5, 0xea, 0x83, 0x41, 0x27, 0xbc, 0xf9, 0x7c, 0xf8, 0x35, 0xb4, 0xc6, - 0xcb, 0x60, 0x9e, 0x99, 0x05, 0xeb, 0xfb, 0xb5, 0x06, 0x17, 0xac, 0xb8, 0xe4, 0x51, 0x2d, 0xe2, - 0xbf, 0x05, 0xb7, 0x24, 0x56, 0xcf, 0xb1, 0xea, 0xcf, 0x21, 0xd0, 0xbc, 0x8a, 0x82, 0xcc, 0x94, - 0x3a, 0x9e, 0xd1, 0xd8, 0xb7, 0x39, 0x8b, 0xb2, 0x20, 0x2b, 0x4c, 0xa9, 0x1b, 0xec, 0x3f, 0xd1, - 0xcf, 0x47, 0x75, 0x57, 0x49, 0xc2, 0x85, 0x6e, 0x1b, 0x0a, 0xc8, 0x4b, 0xe2, 0x5b, 0xae, 0x3a, - 0xbe, 0x4d, 0x15, 0xf0, 0xff, 0x0a, 0xee, 0x30, 0xe4, 0x22, 0xa3, 0x79, 0xc8, 0x77, 0x4d, 0xe2, - 0x3f, 0x8f, 0xcf, 0xdf, 0x98, 0x17, 0xe0, 0xb9, 0x6a, 0x11, 0xf6, 0x9d, 0x16, 0xf1, 0x8a, 0x25, - 0xec, 0x74, 0x24, 0xf3, 0xdc, 0xa6, 0x1a, 0xf9, 0xff, 0xb1, 0xa0, 0x89, 0xbd, 0xa8, 0xa6, 0xba, - 0xf9, 0xb1, 0x3e, 0x76, 0x21, 0xe2, 0x9b, 0x60, 0xc6, 0x85, 0x31, 0xce, 0x60, 0xe9, 0xf4, 0xe9, - 0x92, 0x97, 0x03, 0x5f, 0x23, 0xcc, 0x35, 0xfc, 0xba, 0x30, 0xb5, 0x54, 0xcb, 0x35, 0x24, 0x53, - 0xc5, 0xc4, 0xcd, 0x6e, 0x9c, 0x27, 0x5c, 0x0c, 0x67, 0xab, 0xc0, 0x6c, 0x40, 0x35, 0x8a, 0xff, - 0x5c, 0x7d, 0xaf, 0x6c, 0x75, 0x34, 0x6b, 0xf7, 0xb7, 0xcd, 0xdd, 0x97, 0xfb, 0xff, 0xb5, 0xa0, - 0xfd, 0x5a, 0xef, 0x6a, 0x75, 0x2b, 0xac, 0x0f, 0x5a, 0xd1, 0xd8, 0xb0, 0x62, 0x00, 0x87, 0x46, - 0x66, 0xe3, 0x7e, 0xe5, 0x85, 0x9d, 0x3c, 0xed, 0xd1, 0x66, 0x19, 0xac, 0x4f, 0xf9, 0x5c, 0xb9, - 0xdc, 0x94, 0xd9, 0x15, 0xf0, 0xad, 0xa8, 0xf4, 0xa0, 0x6b, 0x3e, 0xd3, 0xe2, 0xd0, 0x0c, 0x98, - 0x3a, 0xc9, 0x1f, 0x40, 0xeb, 0x24, 0x8e, 0xe6, 0xc1, 0x82, 0xf4, 0xa1, 0x39, 0xcc, 0xb3, 0xa5, - 0xd4, 0xd8, 0x1d, 0x1c, 0xd6, 0x0a, 0x3f, 0xcf, 0x96, 0x4a, 0x86, 0x4a, 0x09, 0xff, 0xf7, 0x00, - 0x15, 0x0d, 0xa7, 0x44, 0x15, 0x8d, 0x37, 0xfc, 0x16, 0x53, 0x26, 0x95, 0x5a, 0x3a, 0x74, 0x07, - 0xc7, 0xff, 0x03, 0xb8, 0xc7, 0x79, 0x10, 0xce, 0x4e, 0xa3, 0x79, 0x8c, 0xad, 0xe3, 0x9a, 0x8b, - 0xb4, 0x8a, 0x97, 0x81, 0xe8, 0x6e, 0xec, 0x22, 0x65, 0x0d, 0x69, 0x34, 0x69, 0xc9, 0x3f, 0x01, - 0x9e, 0x7c, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xb6, 0xb2, 0x98, 0x60, 0x16, 0x10, 0x00, 0x00, + // 1667 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5b, 0x6f, 0xe4, 0x48, + 0x15, 0x96, 0xbb, 0xed, 0x4e, 0xfb, 0x74, 0x92, 0x8d, 0x8a, 0xd1, 0xae, 0x59, 0x10, 0x6a, 0x2c, + 0x2e, 0xe1, 0xb2, 0xc3, 0x2a, 0x2b, 0x24, 0xb4, 0xda, 0x5d, 0x29, 0x97, 0x9d, 0x21, 0x73, 0xcd, + 0x54, 0x27, 0xc3, 0x13, 0x5a, 0x55, 0xdb, 0xd5, 0xdd, 0xa5, 0x75, 0xdb, 0xa6, 0x6c, 0x27, 0x31, + 0xcf, 0xfc, 0x0e, 0x24, 0x24, 0xf8, 0x03, 0x88, 0x47, 0x24, 0xde, 0xf9, 0x01, 0xfc, 0x15, 0x78, + 0x44, 0xa7, 0x2e, 0xee, 0x72, 0xd2, 0x33, 0x1a, 0x24, 0xb4, 0x6f, 0xf5, 0x9d, 0x73, 0xfa, 0x54, + 0xd5, 0xb9, 0x7c, 0x75, 0xdc, 0xb0, 0x2f, 0xf2, 0x9a, 0xcb, 0x9c, 0x65, 0x0f, 0x4b, 0x59, 0xd4, + 0x05, 0x19, 0x5b, 0x1c, 0xff, 0x61, 0x08, 0xa3, 0x59, 0xd1, 0xc8, 0x84, 0x93, 0x7d, 0x18, 0x9c, + 0x9f, 0x45, 0xde, 0xd4, 0x3b, 0x1c, 0xd2, 0xc1, 0xf9, 0x19, 0x21, 0xe0, 0xbf, 0x60, 0x6b, 0x1e, + 0x0d, 0xa6, 0xde, 0x61, 0x48, 0xd5, 0x1a, 0x65, 0x97, 0x6d, 0xc9, 0xa3, 0xa1, 0x96, 0xe1, 0x9a, + 0x7c, 0x08, 0xe3, 0xab, 0x0a, 0xbd, 0xad, 0x79, 0xe4, 0x2b, 0x79, 0x87, 0x51, 0x77, 0xc1, 0xaa, + 0xea, 0xa6, 0x90, 0x69, 0x14, 0x68, 0x9d, 0xc5, 0xe4, 0x00, 0x86, 0x57, 0xf4, 0x59, 0x34, 0x52, + 0x62, 0x5c, 0x92, 0x08, 0x76, 0xce, 0xf8, 0x82, 0x35, 0x59, 0x1d, 0xed, 0x4c, 0xbd, 0xc3, 0x31, + 0xb5, 0x10, 0xfd, 0x5c, 0xf2, 0x8c, 0x2f, 0x25, 0x5b, 0x44, 0x63, 0xed, 0xc7, 0x62, 0xf2, 0x10, + 0xc8, 0x79, 0x5e, 0xf1, 0xa4, 0x91, 0x7c, 0xf6, 0xb5, 0x28, 0x5f, 0x73, 0x29, 0x16, 0x6d, 0x14, + 0x2a, 0x07, 0x5b, 0x34, 0xb8, 0xcb, 0x73, 0x5e, 0x33, 0xdc, 0x1b, 0x94, 0x2b, 0x0b, 0x49, 0x0c, + 0xbb, 0xb3, 0x15, 0x93, 0x3c, 0x9d, 0xf1, 0x44, 0xf2, 0x3a, 0x9a, 0x28, 0x75, 0x4f, 0x86, 0x36, + 0x2f, 0xe5, 0x92, 0xe5, 0xe2, 0xf7, 0xac, 0x16, 0x45, 0x1e, 0xed, 0x6a, 0x1b, 0x57, 0x86, 0x51, + 0xa2, 0x45, 0xc6, 0xa3, 0x3d, 0x1d, 0x25, 0x5c, 0x93, 0xef, 0x42, 0x68, 0x2e, 0x43, 0x2f, 0xa2, + 0x7d, 0xa5, 0xd8, 0x08, 0xe2, 0xbf, 0x79, 0x10, 0x9e, 0xb1, 0x6a, 0x35, 0x2f, 0x98, 0x4c, 0xdf, + 0x29, 0x13, 0x1f, 0x41, 0x90, 0xf0, 0x2c, 0xab, 0xa2, 0xe1, 0x74, 0x78, 0x38, 0x39, 0xfa, 0xe0, + 0x61, 0x97, 0xe2, 0xce, 0xcf, 0x29, 0xcf, 0x32, 0xaa, 0xad, 0xc8, 0xc7, 0x10, 0xd6, 0x7c, 0x5d, + 0x66, 0xac, 0xe6, 0x55, 0xe4, 0xab, 0x9f, 0x90, 0xcd, 0x4f, 0x2e, 0x8d, 0x8a, 0x6e, 0x8c, 0xee, + 0x5d, 0x34, 0xb8, 0x7f, 0xd1, 0xf8, 0x5f, 0x3e, 0xec, 0xf5, 0xb6, 0x23, 0xbb, 0xe0, 0xdd, 0xaa, + 0x93, 0x07, 0xd4, 0xbb, 0x45, 0xd4, 0xaa, 0x53, 0x07, 0xd4, 0x6b, 0x11, 0xdd, 0xa8, 0xca, 0x09, + 0xa8, 0x77, 0x83, 0x68, 0xa5, 0xea, 0x25, 0xa0, 0xde, 0x8a, 0xfc, 0x04, 0x76, 0x7e, 0xd7, 0x70, + 0x29, 0x78, 0x15, 0x05, 0xea, 0x74, 0xef, 0x6d, 0x4e, 0xf7, 0xaa, 0xe1, 0xb2, 0xa5, 0x56, 0x8f, + 0xd1, 0x50, 0xb5, 0xa6, 0x0b, 0x47, 0xad, 0x51, 0x56, 0x63, 0x5d, 0xee, 0x68, 0x19, 0xae, 0x4d, + 0x14, 0x75, 0xb5, 0x60, 0x14, 0x7f, 0x09, 0x3e, 0xbb, 0xe5, 0x55, 0x14, 0x2a, 0xff, 0xdf, 0x7f, + 0x43, 0xc0, 0x1e, 0x1e, 0xdf, 0xf2, 0xea, 0xcb, 0xbc, 0x96, 0x2d, 0x55, 0xe6, 0xe4, 0xc7, 0x30, + 0x4a, 0x8a, 0xac, 0x90, 0x55, 0x04, 0x77, 0x0f, 0x76, 0x8a, 0x72, 0x6a, 0xd4, 0xe4, 0x10, 0x46, + 0x19, 0x5f, 0xf2, 0x3c, 0x55, 0x75, 0x33, 0x39, 0x3a, 0xd8, 0x18, 0x3e, 0x53, 0x72, 0x6a, 0xf4, + 0xe4, 0x53, 0xd8, 0xad, 0xd9, 0x3c, 0xe3, 0x2f, 0x4b, 0x8c, 0x62, 0xa5, 0x6a, 0x68, 0x72, 0xf4, + 0xbe, 0x93, 0x0f, 0x47, 0x4b, 0x7b, 0xb6, 0xe4, 0x33, 0xd8, 0x5d, 0x08, 0x9e, 0xa5, 0xf6, 0xb7, + 0x7b, 0xea, 0x50, 0xd1, 0xe6, 0xb7, 0x94, 0xe7, 0x6c, 0x8d, 0xbf, 0x78, 0x84, 0x66, 0xb4, 0x67, + 0x4d, 0xbe, 0x07, 0x50, 0x8b, 0x35, 0x7f, 0x54, 0xc8, 0x35, 0xab, 0x4d, 0x19, 0x3a, 0x12, 0xf2, + 0x39, 0xec, 0xa5, 0x3c, 0x11, 0x6b, 0x96, 0x5d, 0x64, 0x2c, 0xe1, 0x55, 0xf4, 0x9e, 0x3a, 0x9a, + 0x5b, 0x5d, 0xae, 0x9a, 0xf6, 0xad, 0x3f, 0x7c, 0x0c, 0x61, 0x17, 0x3e, 0xec, 0xef, 0xaf, 0x79, + 0xab, 0x8a, 0x21, 0xa4, 0xb8, 0x24, 0x3f, 0x80, 0xe0, 0x9a, 0x65, 0x8d, 0x2e, 0xe4, 0xc9, 0xd1, + 0xfe, 0xc6, 0xeb, 0xf1, 0xad, 0xa8, 0xa8, 0x56, 0x7e, 0x3a, 0xf8, 0x95, 0x17, 0x3f, 0x86, 0xbd, + 0xde, 0x46, 0x78, 0x70, 0x51, 0x7d, 0x99, 0x2f, 0x0a, 0x99, 0xf0, 0x54, 0xf9, 0x1c, 0x53, 0x47, + 0x42, 0xde, 0x87, 0x51, 0x2a, 0x96, 0xa2, 0xae, 0x4c, 0xb9, 0x19, 0x14, 0xff, 0xdd, 0x83, 0x5d, + 0x37, 0x9a, 0xe4, 0xa7, 0x70, 0x70, 0xcd, 0x65, 0x2d, 0x12, 0x96, 0x5d, 0x8a, 0x35, 0xc7, 0x8d, + 0xd5, 0x4f, 0xc6, 0xf4, 0x9e, 0x9c, 0x7c, 0x0c, 0xa3, 0xaa, 0x90, 0xf5, 0x49, 0xab, 0xaa, 0xf6, + 0x6d, 0x51, 0x36, 0x76, 0xc8, 0x53, 0x37, 0x92, 0x95, 0xa5, 0xc8, 0x97, 0x96, 0x0b, 0x2d, 0x26, + 0x3f, 0x82, 0xfd, 0x85, 0xb8, 0x7d, 0x24, 0x64, 0x55, 0x9f, 0x16, 0x59, 0xb3, 0xce, 0x55, 0x05, + 0x8f, 0xe9, 0x1d, 0xe9, 0x13, 0x7f, 0xec, 0x1d, 0x0c, 0x9e, 0xf8, 0xe3, 0xe0, 0x60, 0x14, 0x97, + 0xb0, 0xdf, 0xdf, 0x09, 0xdb, 0xd2, 0x1e, 0x42, 0x71, 0x82, 0x0e, 0x6f, 0x4f, 0x46, 0xa6, 0x30, + 0x49, 0x45, 0x55, 0x66, 0xac, 0x75, 0x68, 0xc3, 0x15, 0x21, 0x07, 0x5e, 0x8b, 0x4a, 0xcc, 0x33, + 0x4d, 0xe5, 0x63, 0x6a, 0x61, 0xbc, 0x84, 0x40, 0x95, 0xb5, 0x43, 0x42, 0xa1, 0x25, 0x21, 0x45, + 0xfd, 0x03, 0x87, 0xfa, 0x0f, 0x60, 0xf8, 0x6b, 0x7e, 0x6b, 0x5e, 0x03, 0x5c, 0x76, 0x54, 0xe5, + 0x3b, 0x54, 0xf5, 0x00, 0x82, 0xd7, 0x2a, 0xed, 0x9a, 0x42, 0x34, 0x88, 0xbf, 0x80, 0x91, 0x6e, + 0x8b, 0xce, 0xb3, 0xe7, 0x78, 0x9e, 0xc2, 0xe4, 0xa5, 0x14, 0x3c, 0xaf, 0x35, 0xf9, 0x98, 0x2b, + 0x38, 0xa2, 0xf8, 0xaf, 0x1e, 0xf8, 0x2a, 0x4b, 0x31, 0xec, 0x66, 0x7c, 0xc9, 0x92, 0xf6, 0xa4, + 0x68, 0xf2, 0xb4, 0x8a, 0xbc, 0xe9, 0xf0, 0x70, 0x48, 0x7b, 0x32, 0x2c, 0x8f, 0xb9, 0xd6, 0x0e, + 0xa6, 0xc3, 0xc3, 0x90, 0x1a, 0x84, 0x47, 0xcb, 0xd8, 0x9c, 0x67, 0xe6, 0x0a, 0x1a, 0xa0, 0x75, + 0x29, 0xf9, 0x42, 0xdc, 0x9a, 0x6b, 0x18, 0x84, 0xf2, 0xaa, 0x59, 0xa0, 0x5c, 0xdf, 0xc4, 0x20, + 0xbc, 0xc0, 0x9c, 0x55, 0x1d, 0x23, 0xe1, 0x1a, 0x3d, 0x57, 0x09, 0xcb, 0x2c, 0x25, 0x69, 0x10, + 0xff, 0xc3, 0xc3, 0x87, 0x4c, 0x53, 0xec, 0xbd, 0x08, 0x7f, 0x1b, 0xc6, 0x48, 0xbf, 0x5f, 0x5d, + 0x33, 0x69, 0x2e, 0xbc, 0x83, 0xf8, 0x35, 0x93, 0xe4, 0x17, 0x30, 0x52, 0xcd, 0xb1, 0x85, 0xee, + 0xad, 0x3b, 0x15, 0x55, 0x6a, 0xcc, 0x3a, 0x42, 0xf4, 0x1d, 0x42, 0xec, 0x2e, 0x1b, 0xb8, 0x97, + 0xfd, 0x08, 0x02, 0x64, 0xd6, 0x56, 0x9d, 0x7e, 0xab, 0x67, 0xcd, 0xbf, 0xda, 0x2a, 0xbe, 0x82, + 0xbd, 0xde, 0x8e, 0xdd, 0x4e, 0x5e, 0x7f, 0xa7, 0x4d, 0xa3, 0x87, 0xa6, 0xb1, 0xb1, 0x39, 0x2a, + 0x9e, 0xf1, 0xa4, 0xe6, 0xa9, 0xa9, 0xba, 0x0e, 0xc7, 0x7f, 0xf2, 0x36, 0x7e, 0xd5, 0x7e, 0x58, + 0xa2, 0x49, 0xb1, 0x5e, 0xb3, 0x3c, 0x35, 0xae, 0x2d, 0xc4, 0xb8, 0xa5, 0x73, 0xe3, 0x7a, 0x90, + 0xce, 0x11, 0xcb, 0xd2, 0x64, 0x70, 0x20, 0x4b, 0xac, 0x9d, 0x35, 0x67, 0x55, 0x23, 0xf9, 0x9a, + 0xe7, 0xb5, 0x09, 0x81, 0x2b, 0x22, 0x1f, 0xc0, 0x4e, 0xcd, 0x96, 0x5f, 0x21, 0x3d, 0x99, 0x4c, + 0xd6, 0x6c, 0xf9, 0x94, 0xb7, 0xe4, 0x3b, 0x10, 0x2a, 0xbe, 0x54, 0x2a, 0x9d, 0xce, 0xb1, 0x12, + 0x3c, 0xe5, 0x6d, 0xfc, 0x1f, 0x0f, 0x46, 0x33, 0x2e, 0xaf, 0xb9, 0x7c, 0xa7, 0x17, 0xda, 0x9d, + 0x8b, 0x86, 0x6f, 0x99, 0x8b, 0xfc, 0xed, 0x73, 0x51, 0xb0, 0x99, 0x8b, 0x1e, 0x40, 0x30, 0x93, + 0xc9, 0xf9, 0x99, 0x3a, 0xd1, 0x90, 0x6a, 0x80, 0xd5, 0x78, 0x9c, 0xd4, 0xe2, 0x9a, 0x9b, 0x61, + 0xc9, 0xa0, 0x7b, 0x0f, 0xf7, 0x78, 0xcb, 0x84, 0xf2, 0x3f, 0xce, 0x4c, 0xf1, 0x1f, 0x3d, 0x18, + 0x3d, 0x63, 0x6d, 0xd1, 0xd4, 0xf7, 0xaa, 0x76, 0x0a, 0x93, 0xe3, 0xb2, 0xcc, 0x44, 0xd2, 0xeb, + 0x54, 0x47, 0x84, 0x16, 0xcf, 0x9d, 0x7c, 0xe8, 0x58, 0xb8, 0x22, 0x7c, 0x18, 0x4e, 0xd5, 0x30, + 0xa3, 0x27, 0x13, 0xe7, 0x61, 0xd0, 0x33, 0x8c, 0x52, 0x62, 0xd0, 0x8e, 0x9b, 0xba, 0x58, 0x64, + 0xc5, 0x8d, 0x8a, 0xce, 0x98, 0x76, 0x38, 0xfe, 0xe7, 0x00, 0xfc, 0x6f, 0x6a, 0x00, 0xd9, 0x05, + 0x4f, 0x98, 0xe2, 0xf0, 0x44, 0x37, 0x8e, 0xec, 0x38, 0xe3, 0x48, 0x04, 0x3b, 0xad, 0x64, 0xf9, + 0x92, 0x57, 0xd1, 0x58, 0xb1, 0x91, 0x85, 0x4a, 0xa3, 0xfa, 0x4e, 0xcf, 0x21, 0x21, 0xb5, 0xb0, + 0xeb, 0x23, 0x70, 0xfa, 0xe8, 0xe7, 0x66, 0x64, 0x99, 0xdc, 0x7d, 0xe4, 0xb7, 0x4d, 0x2a, 0xff, + 0xbf, 0xd7, 0xf7, 0xdf, 0x1e, 0x04, 0x5d, 0x13, 0x9e, 0xf6, 0x9b, 0xf0, 0x74, 0xd3, 0x84, 0x67, + 0x27, 0xb6, 0x09, 0xcf, 0x4e, 0x10, 0xd3, 0x0b, 0xdb, 0x84, 0xf4, 0x02, 0x93, 0xf5, 0x58, 0x16, + 0x4d, 0x79, 0xd2, 0xea, 0xac, 0x86, 0xb4, 0xc3, 0x58, 0xb9, 0xbf, 0x59, 0x71, 0x69, 0x42, 0x1d, + 0x52, 0x83, 0xb0, 0xce, 0x9f, 0x29, 0x82, 0xd2, 0xc1, 0xd5, 0x80, 0xfc, 0x10, 0x02, 0x8a, 0xc1, + 0x53, 0x11, 0xee, 0xe5, 0x45, 0x89, 0xa9, 0xd6, 0xa2, 0x53, 0xfd, 0x21, 0x63, 0x0a, 0xde, 0x7e, + 0xd6, 0xfc, 0x0c, 0x46, 0xb3, 0x95, 0x58, 0xd4, 0x76, 0xf0, 0xfb, 0x96, 0x43, 0x70, 0x62, 0xcd, + 0x95, 0x8e, 0x1a, 0x93, 0xf8, 0x15, 0x84, 0x9d, 0x70, 0x73, 0x1c, 0xcf, 0x3d, 0x0e, 0x01, 0xff, + 0x2a, 0x17, 0xb5, 0x6d, 0x75, 0x5c, 0xe3, 0x65, 0x5f, 0x35, 0x2c, 0xaf, 0x45, 0xdd, 0xda, 0x56, + 0xb7, 0x38, 0xfe, 0xc4, 0x1c, 0x1f, 0xdd, 0x5d, 0x95, 0x25, 0x97, 0x86, 0x36, 0x34, 0x50, 0x9b, + 0x14, 0x37, 0x5c, 0x33, 0xfe, 0x90, 0x6a, 0x10, 0xff, 0x16, 0xc2, 0xe3, 0x8c, 0xcb, 0x9a, 0x36, + 0x19, 0xdf, 0xf6, 0x12, 0x3f, 0x99, 0xbd, 0x7c, 0x61, 0x4f, 0x80, 0xeb, 0x0d, 0x45, 0x0c, 0xef, + 0x50, 0xc4, 0x53, 0x56, 0xb2, 0xf3, 0x33, 0x55, 0xe7, 0x43, 0x6a, 0x50, 0xfc, 0x67, 0x0f, 0x7c, + 0xe4, 0x22, 0xc7, 0xb5, 0xff, 0x36, 0x1e, 0xbb, 0x90, 0xc5, 0xb5, 0x48, 0xb9, 0xb4, 0x97, 0xb3, + 0x58, 0x05, 0x3d, 0x59, 0xf1, 0xee, 0xc1, 0x37, 0x08, 0x6b, 0x0d, 0xbf, 0x7a, 0x6c, 0x2f, 0x39, + 0xb5, 0x86, 0x62, 0xaa, 0x95, 0x38, 0xd4, 0xcd, 0x9a, 0x92, 0xcb, 0xe3, 0x74, 0x2d, 0xec, 0x34, + 0xe4, 0x48, 0xe2, 0x2f, 0xf4, 0x77, 0xd4, 0x3d, 0x46, 0xf3, 0xb6, 0x7f, 0x73, 0xdd, 0x3d, 0x79, + 0xfc, 0x17, 0x0f, 0x76, 0x9e, 0x9b, 0xe9, 0xcb, 0xbd, 0x85, 0xf7, 0xc6, 0x5b, 0x0c, 0x7a, 0xb7, + 0x38, 0x82, 0x07, 0xd6, 0xa6, 0xb7, 0xbf, 0x8e, 0xc2, 0x56, 0x9d, 0x89, 0xa8, 0xdf, 0x25, 0xeb, + 0x5d, 0x3e, 0xa3, 0x2e, 0xfb, 0x36, 0xdb, 0x12, 0x7e, 0x2f, 0x2b, 0x53, 0x98, 0xd8, 0xcf, 0xc7, + 0x22, 0xb3, 0x0f, 0x8c, 0x2b, 0x8a, 0x8f, 0x60, 0x74, 0x5a, 0xe4, 0x0b, 0xb1, 0x24, 0x87, 0xe0, + 0x1f, 0x37, 0xf5, 0x4a, 0x79, 0x9c, 0x1c, 0x3d, 0x70, 0x1a, 0xbf, 0xa9, 0x57, 0xda, 0x86, 0x2a, + 0x8b, 0xf8, 0x33, 0x80, 0x8d, 0x0c, 0x5f, 0x89, 0x4d, 0x36, 0x5e, 0xf0, 0x1b, 0x2c, 0x99, 0xca, + 0x0c, 0xdf, 0x5b, 0x34, 0xf1, 0xe7, 0x10, 0x9e, 0x34, 0x22, 0x4b, 0xcf, 0xf3, 0x45, 0x81, 0xd4, + 0xf1, 0x9a, 0xcb, 0x6a, 0x93, 0x2f, 0x0b, 0x31, 0xdc, 0xc8, 0x22, 0x5d, 0x0f, 0x19, 0x34, 0x1f, + 0xa9, 0x3f, 0x27, 0x3e, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0xc4, 0xaa, 0x16, 0xae, + 0x10, 0x00, 0x00, } diff --git a/bolt/internal/internal.proto b/bolt/internal/internal.proto index b680b62002..7633ed3af6 100644 --- a/bolt/internal/internal.proto +++ b/bolt/internal/internal.proto @@ -27,33 +27,41 @@ message Dashboard { } message DashboardCell { - int32 x = 1; // X-coordinate of Cell in the Dashboard - int32 y = 2; // Y-coordinate of Cell in the Dashboard - int32 w = 3; // Width of Cell in the Dashboard - int32 h = 4; // Height of Cell in the Dashboard - repeated Query queries = 5; // Time-series data queries for Dashboard - string name = 6; // User-facing name for this Dashboard - string type = 7; // Dashboard visualization type - string ID = 8; // id is the unique id of the dashboard. MIGRATED FIELD added in 1.2.0-beta6 - map axes = 9; // Axes represent the graphical viewport for a cell's visualizations - repeated Color colors = 10; // Colors represent encoding data values to color - Legend legend = 11; // Legend is summary information for a cell - TableOptions tableOptions = 12; // TableOptions for visualization of cell with type 'table' + int32 x = 1; // X-coordinate of Cell in the Dashboard + int32 y = 2; // Y-coordinate of Cell in the Dashboard + int32 w = 3; // Width of Cell in the Dashboard + int32 h = 4; // Height of Cell in the Dashboard + repeated Query queries = 5; // Time-series data queries for Dashboard + string name = 6; // User-facing name for this Dashboard + string type = 7; // Dashboard visualization type + string ID = 8; // id is the unique id of the dashboard. MIGRATED FIELD added in 1.2.0-beta6 + map axes = 9; // Axes represent the graphical viewport for a cell's visualizations + repeated Color colors = 10; // Colors represent encoding data values to color + Legend legend = 11; // Legend is summary information for a cell + TableOptions tableOptions = 12; // TableOptions for visualization of cell with type 'table' + repeated RenamableField fieldOptions = 13; // Options for each of the fields returned in a cell + string timeFormat = 14; // format for time + DecimalPlaces decimalPlaces = 15; // Represents how precise the values of this field should be +} + +message DecimalPlaces { + bool isEnforced = 1; // whether decimal places should be enforced + int32 digits = 2; // the number of digits to display after decical point } message TableOptions { - string timeFormat = 1; // format for time + reserved 1; bool verticalTimeAxis = 2; // time axis should be a column not row RenamableField sortBy = 3; // which column should a table be sorted by string wrapping = 4; // option for text wrapping - repeated RenamableField fieldNames = 5; // names and renames for column/row fields + reserved 5; bool fixFirstColumn = 6; // first column should be fixed/frozen } message RenamableField { string internalName = 1; // name of column string displayName = 2; // what column is renamed to - bool visible = 3; // Represents whether RenamableField is visible + bool visible = 3; // Represents whether RenamableField is visible } message Color { diff --git a/bolt/internal/internal_test.go b/bolt/internal/internal_test.go index 75c87816f1..ff4bf0ce94 100644 --- a/bolt/internal/internal_test.go +++ b/bolt/internal/internal_test.go @@ -194,10 +194,9 @@ func Test_MarshalDashboard(t *testing.T) { Value: "100", }, }, - TableOptions: chronograf.TableOptions{ - TimeFormat: "", - FieldNames: []chronograf.RenamableField{}, - }, + TableOptions: chronograf.TableOptions{}, + FieldOptions: []chronograf.RenamableField{}, + TimeFormat: "", }, }, Templates: []chronograf.Template{}, @@ -260,10 +259,10 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { Type: "static", Orientation: "bottom", }, - TableOptions: chronograf.TableOptions{ - TimeFormat: "MM:DD:YYYY", - }, - Type: "line", + TableOptions: chronograf.TableOptions{}, + TimeFormat: "MM:DD:YYYY", + FieldOptions: []chronograf.RenamableField{}, + Type: "line", }, }, Templates: []chronograf.Template{}, @@ -317,11 +316,10 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { Type: "static", Orientation: "bottom", }, - TableOptions: chronograf.TableOptions{ - TimeFormat: "MM:DD:YYYY", - FieldNames: []chronograf.RenamableField{}, - }, - Type: "line", + TableOptions: chronograf.TableOptions{}, + FieldOptions: []chronograf.RenamableField{}, + TimeFormat: "MM:DD:YYYY", + Type: "line", }, }, Templates: []chronograf.Template{}, @@ -380,10 +378,10 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { Value: "100", }, }, - Type: "line", - TableOptions: chronograf.TableOptions{ - TimeFormat: "MM:DD:YYYY", - }, + Type: "line", + TableOptions: chronograf.TableOptions{}, + FieldOptions: []chronograf.RenamableField{}, + TimeFormat: "MM:DD:YYYY", }, }, Templates: []chronograf.Template{}, @@ -433,11 +431,10 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { Value: "100", }, }, - TableOptions: chronograf.TableOptions{ - TimeFormat: "MM:DD:YYYY", - FieldNames: []chronograf.RenamableField{}, - }, - Type: "line", + TableOptions: chronograf.TableOptions{}, + FieldOptions: []chronograf.RenamableField{}, + TimeFormat: "MM:DD:YYYY", + Type: "line", }, }, Templates: []chronograf.Template{}, @@ -468,14 +465,13 @@ func Test_MarshalDashboard_WithEmptyCellType(t *testing.T) { ID: 1, Cells: []chronograf.DashboardCell{ { - ID: "9b5367de-c552-4322-a9e8-7f384cbd235c", - Type: "line", - Queries: []chronograf.DashboardQuery{}, - Axes: map[string]chronograf.Axis{}, - CellColors: []chronograf.CellColor{}, - TableOptions: chronograf.TableOptions{ - FieldNames: []chronograf.RenamableField{}, - }, + ID: "9b5367de-c552-4322-a9e8-7f384cbd235c", + Type: "line", + Queries: []chronograf.DashboardQuery{}, + Axes: map[string]chronograf.Axis{}, + CellColors: []chronograf.CellColor{}, + TableOptions: chronograf.TableOptions{}, + FieldOptions: []chronograf.RenamableField{}, }, }, Templates: []chronograf.Template{}, diff --git a/chronograf.go b/chronograf.go index bdc9d5fc9d..47ece6d953 100644 --- a/chronograf.go +++ b/chronograf.go @@ -563,18 +563,21 @@ type Legend struct { // DashboardCell holds visual and query information for a cell type DashboardCell struct { - ID string `json:"i"` - X int32 `json:"x"` - Y int32 `json:"y"` - W int32 `json:"w"` - H int32 `json:"h"` - Name string `json:"name"` - Queries []DashboardQuery `json:"queries"` - Axes map[string]Axis `json:"axes"` - Type string `json:"type"` - CellColors []CellColor `json:"colors"` - Legend Legend `json:"legend"` - TableOptions TableOptions `json:"tableOptions,omitempty"` + ID string `json:"i"` + X int32 `json:"x"` + Y int32 `json:"y"` + W int32 `json:"w"` + H int32 `json:"h"` + Name string `json:"name"` + Queries []DashboardQuery `json:"queries"` + Axes map[string]Axis `json:"axes"` + Type string `json:"type"` + CellColors []CellColor `json:"colors"` + Legend Legend `json:"legend"` + TableOptions TableOptions `json:"tableOptions,omitempty"` + FieldOptions []RenamableField `json:"fieldOptions"` + TimeFormat string `json:"timeFormat"` + DecimalPlaces DecimalPlaces `json:"decimalPlaces"` } // RenamableField is a column/row field in a DashboardCell of type Table @@ -586,12 +589,16 @@ type RenamableField struct { // TableOptions is a type of options for a DashboardCell with type Table type TableOptions struct { - TimeFormat string `json:"timeFormat"` - VerticalTimeAxis bool `json:"verticalTimeAxis"` - SortBy RenamableField `json:"sortBy"` - Wrapping string `json:"wrapping"` - FieldNames []RenamableField `json:"fieldNames"` - FixFirstColumn bool `json:"fixFirstColumn"` + VerticalTimeAxis bool `json:"verticalTimeAxis"` + SortBy RenamableField `json:"sortBy"` + Wrapping string `json:"wrapping"` + FixFirstColumn bool `json:"fixFirstColumn"` +} + +// DecimalPlaces indicates whether decimal places should be enforced, and how many digits it should show. +type DecimalPlaces struct { + IsEnforced bool `json:"isEnforced"` + Digits int32 `json:"digits"` } // DashboardsStore is the storage and retrieval of dashboards diff --git a/integrations/server_test.go b/integrations/server_test.go index 8cce376861..e7ce7995ef 100644 --- a/integrations/server_test.go +++ b/integrations/server_test.go @@ -166,8 +166,8 @@ func TestServer(t *testing.T) { "id": "5000", "name": "Kapa 1", "url": "http://localhost:9092", - "active": true, - "insecureSkipVerify": false, + "active": true, + "insecureSkipVerify": false, "links": { "proxy": "/chronograf/v1/sources/5000/kapacitors/5000/proxy", "self": "/chronograf/v1/sources/5000/kapacitors/5000", @@ -225,8 +225,8 @@ func TestServer(t *testing.T) { "id": "5000", "name": "Kapa 1", "url": "http://localhost:9092", - "active": true, - "insecureSkipVerify": false, + "active": true, + "insecureSkipVerify": false, "links": { "proxy": "/chronograf/v1/sources/5000/kapacitors/5000/proxy", "self": "/chronograf/v1/sources/5000/kapacitors/5000", @@ -292,7 +292,7 @@ func TestServer(t *testing.T) { "default": true, "telegraf": "telegraf", "organization": "howdy", - "defaultRP": "", + "defaultRP": "", "links": { "self": "/chronograf/v1/sources/5000", "kapacitors": "/chronograf/v1/sources/5000/kapacitors", @@ -304,7 +304,7 @@ func TestServer(t *testing.T) { "roles": "/chronograf/v1/sources/5000/roles", "databases": "/chronograf/v1/sources/5000/dbs", "annotations": "/chronograf/v1/sources/5000/annotations", - "health": "/chronograf/v1/sources/5000/health" + "health": "/chronograf/v1/sources/5000/health" } } ] @@ -546,19 +546,23 @@ func TestServer(t *testing.T) { "legend":{ "type": "static", "orientation": "bottom" - }, - "tableOptions":{ - "timeFormat": "", - "verticalTimeAxis": false, - "sortBy":{ - "internalName": "", - "displayName": "", - "visible": false - }, - "wrapping": "", - "fieldNames": null, - "fixFirstColumn": false - }, + }, + "tableOptions":{ + "verticalTimeAxis": false, + "sortBy":{ + "internalName": "", + "displayName": "", + "visible": false + }, + "wrapping": "", + "fixFirstColumn": false + }, + "fieldOptions": null, + "timeFormat": "", + "decimalPlaces":{ + "isEnforced": false, + "digits": 0 + }, "links": { "self": "/chronograf/v1/dashboards/1000/cells/8f61c619-dd9b-4761-8aa8-577f27247093" } @@ -797,22 +801,26 @@ func TestServer(t *testing.T) { "name": "comet", "value": "100" } - ], - "tableOptions":{ - "timeFormat":"", - "verticalTimeAxis":false, - "sortBy":{ - "internalName":"", - "displayName":"", - "visible":false - }, - "wrapping":"", - "fieldNames":null, - "fixFirstColumn":false - }, - "legend":{ - "type": "static", - "orientation": "bottom" + ], + "legend": { + "type": "static", + "orientation": "bottom" + }, + "tableOptions":{ + "verticalTimeAxis": false, + "sortBy":{ + "internalName": "", + "displayName": "", + "visible": false + }, + "wrapping": "", + "fixFirstColumn": false + }, + "fieldOptions": null, + "timeFormat": "", + "decimalPlaces":{ + "isEnforced": false, + "digits": 0 }, "links": { "self": "/chronograf/v1/dashboards/1000/cells/8f61c619-dd9b-4761-8aa8-577f27247093" @@ -2143,7 +2151,7 @@ func TestServer(t *testing.T) { wants: wants{ statusCode: 403, body: ` - { + { "code": 403, "message": "user not found" }`, @@ -2363,61 +2371,61 @@ func TestServer(t *testing.T) { statusCode: 200, body: ` { - "links": { - "self": "/chronograf/v1/mappings" - }, - "mappings": [ - { - "links": { - "self": "/chronograf/v1/mappings/1" - }, - "id": "1", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "influxdata" - }, - { - "links": { - "self": "/chronograf/v1/mappings/2" - }, - "id": "2", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/3" - }, - "id": "3", - "organizationId": "2", - "provider": "github", - "scheme": "*", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/4" - }, - "id": "4", - "organizationId": "3", - "provider": "auth0", - "scheme": "ldap", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/default" - }, - "id": "default", - "organizationId": "default", - "provider": "*", - "scheme": "*", - "providerOrganization": "*" - } - ] + "links": { + "self": "/chronograf/v1/mappings" + }, + "mappings": [ + { + "links": { + "self": "/chronograf/v1/mappings/1" + }, + "id": "1", + "organizationId": "1", + "provider": "*", + "scheme": "*", + "providerOrganization": "influxdata" + }, + { + "links": { + "self": "/chronograf/v1/mappings/2" + }, + "id": "2", + "organizationId": "1", + "provider": "*", + "scheme": "*", + "providerOrganization": "*" + }, + { + "links": { + "self": "/chronograf/v1/mappings/3" + }, + "id": "3", + "organizationId": "2", + "provider": "github", + "scheme": "*", + "providerOrganization": "*" + }, + { + "links": { + "self": "/chronograf/v1/mappings/4" + }, + "id": "4", + "organizationId": "3", + "provider": "auth0", + "scheme": "ldap", + "providerOrganization": "*" + }, + { + "links": { + "self": "/chronograf/v1/mappings/default" + }, + "id": "default", + "organizationId": "default", + "provider": "*", + "scheme": "*", + "providerOrganization": "*" + } + ] } `, }, @@ -2693,40 +2701,40 @@ func TestServer(t *testing.T) { wants: wants{ statusCode: 200, body: ` - { - "layouts": "/chronograf/v1/layouts", - "users": "/chronograf/v1/organizations/default/users", - "allUsers": "/chronograf/v1/users", - "organizations": "/chronograf/v1/organizations", - "mappings": "/chronograf/v1/mappings", - "sources": "/chronograf/v1/sources", - "me": "/chronograf/v1/me", - "environment": "/chronograf/v1/env", - "dashboards": "/chronograf/v1/dashboards", - "config": { - "self": "/chronograf/v1/config", - "auth": "/chronograf/v1/config/auth" - }, - "auth": [ - { - "name": "github", - "label": "Github", - "login": "/oauth/github/login", - "logout": "/oauth/github/logout", - "callback": "/oauth/github/callback" - } - ], - "logout": "/oauth/logout", - "external": { - "statusFeed": "" - }, - "ifql": { - "ast": "/chronograf/v1/ifql/ast", - "self": "/chronograf/v1/ifql", - "suggestions": "/chronograf/v1/ifql/suggestions" - } - } - `, + { + "layouts": "/chronograf/v1/layouts", + "users": "/chronograf/v1/organizations/default/users", + "allUsers": "/chronograf/v1/users", + "organizations": "/chronograf/v1/organizations", + "mappings": "/chronograf/v1/mappings", + "sources": "/chronograf/v1/sources", + "me": "/chronograf/v1/me", + "environment": "/chronograf/v1/env", + "dashboards": "/chronograf/v1/dashboards", + "config": { + "self": "/chronograf/v1/config", + "auth": "/chronograf/v1/config/auth" + }, + "auth": [ + { + "name": "github", + "label": "Github", + "login": "/oauth/github/login", + "logout": "/oauth/github/logout", + "callback": "/oauth/github/callback" + } + ], + "logout": "/oauth/logout", + "external": { + "statusFeed": "" + }, + "ifql": { + "ast": "/chronograf/v1/ifql/ast", + "self": "/chronograf/v1/ifql", + "suggestions": "/chronograf/v1/ifql/suggestions" + } + } + `, }, }, { @@ -2781,40 +2789,40 @@ func TestServer(t *testing.T) { wants: wants{ statusCode: 200, body: ` - { - "layouts": "/chronograf/v1/layouts", - "users": "/chronograf/v1/organizations/1/users", - "allUsers": "/chronograf/v1/users", - "organizations": "/chronograf/v1/organizations", - "mappings": "/chronograf/v1/mappings", - "sources": "/chronograf/v1/sources", - "me": "/chronograf/v1/me", - "environment": "/chronograf/v1/env", - "dashboards": "/chronograf/v1/dashboards", - "config": { - "self": "/chronograf/v1/config", - "auth": "/chronograf/v1/config/auth" - }, - "auth": [ - { - "name": "github", - "label": "Github", - "login": "/oauth/github/login", - "logout": "/oauth/github/logout", - "callback": "/oauth/github/callback" - } - ], - "logout": "/oauth/logout", - "external": { - "statusFeed": "" - }, - "ifql": { - "ast": "/chronograf/v1/ifql/ast", - "self": "/chronograf/v1/ifql", - "suggestions": "/chronograf/v1/ifql/suggestions" - } - } - `, + { + "layouts": "/chronograf/v1/layouts", + "users": "/chronograf/v1/organizations/1/users", + "allUsers": "/chronograf/v1/users", + "organizations": "/chronograf/v1/organizations", + "mappings": "/chronograf/v1/mappings", + "sources": "/chronograf/v1/sources", + "me": "/chronograf/v1/me", + "environment": "/chronograf/v1/env", + "dashboards": "/chronograf/v1/dashboards", + "config": { + "self": "/chronograf/v1/config", + "auth": "/chronograf/v1/config/auth" + }, + "auth": [ + { + "name": "github", + "label": "Github", + "login": "/oauth/github/login", + "logout": "/oauth/github/logout", + "callback": "/oauth/github/callback" + } + ], + "logout": "/oauth/logout", + "external": { + "statusFeed": "" + }, + "ifql": { + "ast": "/chronograf/v1/ifql/ast", + "self": "/chronograf/v1/ifql", + "suggestions": "/chronograf/v1/ifql/suggestions" + } + } + `, }, }, } diff --git a/server/cells_test.go b/server/cells_test.go index 38c2ef5c5e..8eeac56728 100644 --- a/server/cells_test.go +++ b/server/cells_test.go @@ -532,7 +532,7 @@ func TestService_ReplaceDashboardCell(t *testing.T) { } } `))), - want: `{"i":"3c5c4102-fa40-4585-a8f9-917c77e37192","x":0,"y":0,"w":4,"h":4,"name":"Untitled Cell","queries":[{"query":"SELECT mean(\"usage_user\") AS \"mean_usage_user\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time \u003e :dashboardTime: AND \"cpu\"=:cpu: GROUP BY :interval: FILL(null)","queryConfig":{"id":"3cd3eaa4-a4b8-44b3-b69e-0c7bf6b91d9e","database":"telegraf","measurement":"cpu","retentionPolicy":"autogen","fields":[{"value":"mean","type":"func","alias":"mean_usage_user","args":[{"value":"usage_user","type":"field","alias":""}]}],"tags":{"cpu":["ChristohersMBP2.lan"]},"groupBy":{"time":"2s","tags":[]},"areTagsAccepted":true,"fill":"null","rawText":"SELECT mean(\"usage_user\") AS \"mean_usage_user\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time \u003e :dashboardTime: AND \"cpu\"=:cpu: GROUP BY :interval: FILL(null)","range":{"upper":"","lower":"now() - 15m"},"shifts":[]},"source":""}],"axes":{"x":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""},"y":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""},"y2":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""}},"type":"line","colors":[{"id":"0","type":"min","hex":"#00C9FF","name":"laser","value":"0"},{"id":"1","type":"max","hex":"#9394FF","name":"comet","value":"100"}],"legend":{},"tableOptions":{"timeFormat":"","verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fieldNames":null,"fixFirstColumn":false},"links":{"self":"/chronograf/v1/dashboards/1/cells/3c5c4102-fa40-4585-a8f9-917c77e37192"}} + want: `{"i":"3c5c4102-fa40-4585-a8f9-917c77e37192","x":0,"y":0,"w":4,"h":4,"name":"Untitled Cell","queries":[{"query":"SELECT mean(\"usage_user\") AS \"mean_usage_user\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time \u003e :dashboardTime: AND \"cpu\"=:cpu: GROUP BY :interval: FILL(null)","queryConfig":{"id":"3cd3eaa4-a4b8-44b3-b69e-0c7bf6b91d9e","database":"telegraf","measurement":"cpu","retentionPolicy":"autogen","fields":[{"value":"mean","type":"func","alias":"mean_usage_user","args":[{"value":"usage_user","type":"field","alias":""}]}],"tags":{"cpu":["ChristohersMBP2.lan"]},"groupBy":{"time":"2s","tags":[]},"areTagsAccepted":true,"fill":"null","rawText":"SELECT mean(\"usage_user\") AS \"mean_usage_user\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time \u003e :dashboardTime: AND \"cpu\"=:cpu: GROUP BY :interval: FILL(null)","range":{"upper":"","lower":"now() - 15m"},"shifts":[]},"source":""}],"axes":{"x":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""},"y":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""},"y2":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"","scale":""}},"type":"line","colors":[{"id":"0","type":"min","hex":"#00C9FF","name":"laser","value":"0"},{"id":"1","type":"max","hex":"#9394FF","name":"comet","value":"100"}],"legend":{},"tableOptions":{"verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fixFirstColumn":false},"fieldOptions":null,"timeFormat":"","decimalPlaces":{"isEnforced":false,"digits":0},"links":{"self":"/chronograf/v1/dashboards/1/cells/3c5c4102-fa40-4585-a8f9-917c77e37192"}} `, }, { diff --git a/server/swagger.json b/server/swagger.json index cc1f15706c..8f2188cf16 100644 --- a/server/swagger.json +++ b/server/swagger.json @@ -4653,11 +4653,6 @@ } }, "tableOptions": { - "timeFormat": { - "description": - "timeFormat describes the display format for time values according to moment.js date formatting", - "type": "string" - }, "verticalTimeAxis": { "description": "verticalTimeAxis describes the orientation of the table by indicating whether the time axis will be displayed vertically", @@ -4675,20 +4670,41 @@ "type": "string", "enum": ["truncate", "wrap", "single-line"] }, - "fieldNames": { - "description": - "fieldNames represent the fields retrieved by the query with customization options", - "type": "array", - "items": { - "$ref": "#/definitions/RenamableField" - } - }, "fixFirstColumn": { "description": "fixFirstColumn indicates whether the first column of the table should be locked", "type": "boolean" } }, + "fieldOptions": { + "description": + "fieldOptions represent the fields retrieved by the query with customization options", + "type": "array", + "items": { + "$ref": "#/definitions/RenamableField" + } + }, + "timeFormat": { + "description": + "timeFormat describes the display format for time values according to moment.js date formatting", + "type": "string" + }, + "decimalPoints": { + "description": + "decimal points indicates whether and how many digits to show after decimal point", + "type": "object", + "properties": { + "isEnforced": { + "description": + "Indicates whether decimal point setting should be enforced", + "type": "bool" + }, + "digits": { + "description": "The number of digits after decimal to display", + "type": "integer" + } + } + }, "links": { "type": "object", "properties": { diff --git a/ui/src/admin/components/chronograf/AdminTabs.js b/ui/src/admin/components/chronograf/AdminTabs.js deleted file mode 100644 index 48ac81fd83..0000000000 --- a/ui/src/admin/components/chronograf/AdminTabs.js +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' - -import { - isUserAuthorized, - ADMIN_ROLE, - SUPERADMIN_ROLE, -} from 'src/auth/Authorized' - -import {Tab, Tabs, TabPanel, TabPanels, TabList} from 'shared/components/Tabs' -import OrganizationsPage from 'src/admin/containers/chronograf/OrganizationsPage' -import UsersPage from 'src/admin/containers/chronograf/UsersPage' -import ProvidersPage from 'src/admin/containers/ProvidersPage' -import AllUsersPage from 'src/admin/containers/chronograf/AllUsersPage' - -const ORGANIZATIONS_TAB_NAME = 'All Orgs' -const PROVIDERS_TAB_NAME = 'Org Mappings' -const CURRENT_ORG_USERS_TAB_NAME = 'Current Org' -const ALL_USERS_TAB_NAME = 'All Users' - -const AdminTabs = ({ - me: {currentOrganization: meCurrentOrganization, role: meRole, id: meID}, -}) => { - const tabs = [ - { - requiredRole: ADMIN_ROLE, - type: CURRENT_ORG_USERS_TAB_NAME, - component: ( - - ), - }, - { - requiredRole: SUPERADMIN_ROLE, - type: ALL_USERS_TAB_NAME, - component: , - }, - { - requiredRole: SUPERADMIN_ROLE, - type: ORGANIZATIONS_TAB_NAME, - component: ( - - ), - }, - { - requiredRole: SUPERADMIN_ROLE, - type: PROVIDERS_TAB_NAME, - component: , - }, - ].filter(t => isUserAuthorized(meRole, t.requiredRole)) - - return ( - - - {tabs.map((t, i) => {tabs[i].type})} - - - {tabs.map((t, i) => ( - {t.component} - ))} - - - ) -} - -const {shape, string} = PropTypes - -AdminTabs.propTypes = { - me: shape({ - id: string.isRequired, - role: string.isRequired, - currentOrganization: shape({ - name: string.isRequired, - id: string.isRequired, - }), - }).isRequired, -} - -export default AdminTabs diff --git a/ui/src/admin/containers/chronograf/AdminChronografPage.js b/ui/src/admin/containers/chronograf/AdminChronografPage.js index 2815bd1fa4..5e1eb9f77d 100644 --- a/ui/src/admin/containers/chronograf/AdminChronografPage.js +++ b/ui/src/admin/containers/chronograf/AdminChronografPage.js @@ -2,10 +2,52 @@ import React from 'react' import PropTypes from 'prop-types' import {connect} from 'react-redux' -import AdminTabs from 'src/admin/components/chronograf/AdminTabs' +import SubSections from 'src/shared/components/SubSections' import FancyScrollbar from 'shared/components/FancyScrollbar' -const AdminChronografPage = ({me}) => ( +import UsersPage from 'src/admin/containers/chronograf/UsersPage' +import AllUsersPage from 'src/admin/containers/chronograf/AllUsersPage' +import OrganizationsPage from 'src/admin/containers/chronograf/OrganizationsPage' +import ProvidersPage from 'src/admin/containers/ProvidersPage' + +import { + isUserAuthorized, + ADMIN_ROLE, + SUPERADMIN_ROLE, +} from 'src/auth/Authorized' + +const sections = me => [ + { + url: 'current-organization', + name: 'Current Org', + enabled: isUserAuthorized(me.role, ADMIN_ROLE), + component: ( + + ), + }, + { + url: 'all-users', + name: 'All Users', + enabled: isUserAuthorized(me.role, SUPERADMIN_ROLE), + component: , + }, + { + url: 'all-organizations', + name: 'All Orgs', + enabled: isUserAuthorized(me.role, SUPERADMIN_ROLE), + component: ( + + ), + }, + { + url: 'organization-mappings', + name: 'Org Mappings', + enabled: isUserAuthorized(me.role, SUPERADMIN_ROLE), + component: , + }, +] + +const AdminChronografPage = ({me, source, params: {tab}}) => (
@@ -16,9 +58,12 @@ const AdminChronografPage = ({me}) => (
-
- -
+
@@ -35,6 +80,15 @@ AdminChronografPage.propTypes = { id: string.isRequired, }), }).isRequired, + params: shape({ + tab: string, + }).isRequired, + source: shape({ + id: string.isRequired, + links: shape({ + users: string.isRequired, + }), + }).isRequired, } const mapStateToProps = ({auth: {me}}) => ({ diff --git a/ui/src/dashboards/actions/cellEditorOverlay.js b/ui/src/dashboards/actions/cellEditorOverlay.js index f9efe0de08..3e2d847c07 100644 --- a/ui/src/dashboards/actions/cellEditorOverlay.js +++ b/ui/src/dashboards/actions/cellEditorOverlay.js @@ -64,3 +64,24 @@ export const updateLineColors = lineColors => ({ lineColors, }, }) + +export const changeTimeFormat = timeFormat => ({ + type: 'CHANGE_TIME_FORMAT', + payload: { + timeFormat, + }, +}) + +export const changeDecimalPlaces = decimalPlaces => ({ + type: 'CHANGE_DECIMAL_PLACES', + payload: { + decimalPlaces, + }, +}) + +export const updateFieldOptions = fieldOptions => ({ + type: 'UPDATE_FIELD_OPTIONS', + payload: { + fieldOptions, + }, +}) diff --git a/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx b/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx index bda8f30da6..9a5eec35c0 100644 --- a/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx +++ b/ui/src/dashboards/components/GraphOptionsCustomizableField.tsx @@ -21,7 +21,7 @@ interface RenamableField { visible: boolean } -interface GraphOptionsCustomizableFieldProps { +interface Props { internalName: string displayName: string visible: boolean @@ -36,7 +36,7 @@ interface GraphOptionsCustomizableFieldProps { moveField: (dragIndex: number, hoverIndex: number) => void } -const fieldSource: DragSourceSpec = { +const fieldSource: DragSourceSpec = { beginDrag(props) { return { id: props.id, @@ -112,9 +112,7 @@ function MyDragSource(dragv1, dragv2, dragfunc1) { isDragging: monitor.isDragging(), }) ) -export default class GraphOptionsCustomizableField extends Component< - GraphOptionsCustomizableFieldProps -> { +export default class GraphOptionsCustomizableField extends Component { constructor(props) { super(props) diff --git a/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx b/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx new file mode 100644 index 0000000000..0244c7fced --- /dev/null +++ b/ui/src/dashboards/components/GraphOptionsDecimalPlaces.tsx @@ -0,0 +1,60 @@ +import React, {PureComponent} from 'react' +import {ErrorHandling} from 'src/shared/decorators/errors' +import OptIn from 'src/shared/components/OptIn' + +interface DecimalPlaces { + isEnforced: boolean + digits: number +} + +interface Props extends DecimalPlaces { + onDecimalPlacesChange: (decimalPlaces: DecimalPlaces) => void +} + +const fixedValueString = 'fixed' + +@ErrorHandling +class GraphOptionsDecimalPlaces extends PureComponent { + constructor(props: Props) { + super(props) + } + + public onSetValue = (valueFromSelector: string): void => { + let digits + let isEnforced + if (valueFromSelector === fixedValueString) { + digits = this.props.digits + isEnforced = false + } else if (valueFromSelector === '') { + digits = this.props.digits + isEnforced = true + } else { + digits = Number(valueFromSelector) + if (digits < 0) { + digits = 0 + } + isEnforced = true + } + this.props.onDecimalPlacesChange({digits, isEnforced}) + } + + public render() { + const {digits, isEnforced} = this.props + return ( +
+ + +
+ ) + } +} + +export default GraphOptionsDecimalPlaces diff --git a/ui/src/dashboards/components/GraphOptionsSortBy.tsx b/ui/src/dashboards/components/GraphOptionsSortBy.tsx index e831549e09..c76bbf3acb 100644 --- a/ui/src/dashboards/components/GraphOptionsSortBy.tsx +++ b/ui/src/dashboards/components/GraphOptionsSortBy.tsx @@ -25,7 +25,7 @@ const GraphOptionsSortBy = ({ const selectedValue = selected.displayName || selected.internalName return (
- + { const showCustom = !formatOption || customFormat return ( -
+