feat(server): add new color property to annotation
parent
38ee6bbad9
commit
0756097cce
|
@ -535,6 +535,7 @@ var annotationTagsBlacklist = map[string]bool{
|
||||||
"endTime": true,
|
"endTime": true,
|
||||||
"modified_time_ns": true,
|
"modified_time_ns": true,
|
||||||
"text": true,
|
"text": true,
|
||||||
|
"color": true,
|
||||||
"type": true,
|
"type": true,
|
||||||
"id": true,
|
"id": true,
|
||||||
}
|
}
|
||||||
|
@ -566,6 +567,7 @@ type Annotation struct {
|
||||||
StartTime time.Time // StartTime starts the annotation
|
StartTime time.Time // StartTime starts the annotation
|
||||||
EndTime time.Time // EndTime ends the annotation
|
EndTime time.Time // EndTime ends the annotation
|
||||||
Text string // Text is the associated user-facing text describing the annotation
|
Text string // Text is the associated user-facing text describing the annotation
|
||||||
|
Color string // Color associated with the annotation
|
||||||
Tags AnnotationTags // Tags is a collection of user defined key/value pairs that contextualize the annotation
|
Tags AnnotationTags // Tags is a collection of user defined key/value pairs that contextualize the annotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,7 @@ func toPoint(anno *chronograf.Annotation, now time.Time) chronograf.Point {
|
||||||
"start_time": anno.StartTime.UnixNano(),
|
"start_time": anno.StartTime.UnixNano(),
|
||||||
"modified_time_ns": int64(now.UnixNano()),
|
"modified_time_ns": int64(now.UnixNano()),
|
||||||
"text": anno.Text,
|
"text": anno.Text,
|
||||||
|
"color": anno.Color,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,6 +303,9 @@ func (r *influxResults) Annotations() (res []chronograf.Annotation, err error) {
|
||||||
if anno.ID, err = v.String(i); err != nil {
|
if anno.ID, err = v.String(i); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if colorIndex, found := columnIndex["color"]; found {
|
||||||
|
anno.Color, _ = v.String(colorIndex)
|
||||||
|
}
|
||||||
|
|
||||||
anno.Tags = chronograf.AnnotationTags{}
|
anno.Tags = chronograf.AnnotationTags{}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ func Test_toPoint(t *testing.T) {
|
||||||
"start_time": time.Time{}.UnixNano(),
|
"start_time": time.Time{}.UnixNano(),
|
||||||
"modified_time_ns": int64(time.Unix(0, 0).UnixNano()),
|
"modified_time_ns": int64(time.Unix(0, 0).UnixNano()),
|
||||||
"text": "mytext",
|
"text": "mytext",
|
||||||
|
"color": "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -50,6 +51,7 @@ func Test_toPoint(t *testing.T) {
|
||||||
Text: "mytext",
|
Text: "mytext",
|
||||||
StartTime: time.Unix(100, 0),
|
StartTime: time.Unix(100, 0),
|
||||||
EndTime: time.Unix(200, 0),
|
EndTime: time.Unix(200, 0),
|
||||||
|
Color: "red",
|
||||||
},
|
},
|
||||||
now: time.Unix(0, 0),
|
now: time.Unix(0, 0),
|
||||||
want: chronograf.Point{
|
want: chronograf.Point{
|
||||||
|
@ -65,6 +67,7 @@ func Test_toPoint(t *testing.T) {
|
||||||
"start_time": time.Unix(100, 0).UnixNano(),
|
"start_time": time.Unix(100, 0).UnixNano(),
|
||||||
"modified_time_ns": int64(time.Unix(0, 0).UnixNano()),
|
"modified_time_ns": int64(time.Unix(0, 0).UnixNano()),
|
||||||
"text": "mytext",
|
"text": "mytext",
|
||||||
|
"color": "red",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,6 +28,7 @@ type annotationResponse struct {
|
||||||
StartTime string `json:"startTime"` // StartTime in RFC3339 of the start of the annotation
|
StartTime string `json:"startTime"` // StartTime in RFC3339 of the start of the annotation
|
||||||
EndTime string `json:"endTime"` // EndTime in RFC3339 of the end of the annotation
|
EndTime string `json:"endTime"` // EndTime in RFC3339 of the end of the annotation
|
||||||
Text string `json:"text"` // Text is the associated user-facing text describing the annotation
|
Text string `json:"text"` // Text is the associated user-facing text describing the annotation
|
||||||
|
Color string `json:"color"` // Optional annotation color
|
||||||
Tags chronograf.AnnotationTags `json:"tags"` // Tags is a collection of user defined key/value pairs that contextualize the annotation
|
Tags chronograf.AnnotationTags `json:"tags"` // Tags is a collection of user defined key/value pairs that contextualize the annotation
|
||||||
Links annotationLinks `json:"links"`
|
Links annotationLinks `json:"links"`
|
||||||
}
|
}
|
||||||
|
@ -39,6 +40,7 @@ func newAnnotationResponse(src chronograf.Source, a *chronograf.Annotation) anno
|
||||||
StartTime: a.StartTime.UTC().Format(timeMilliFormat),
|
StartTime: a.StartTime.UTC().Format(timeMilliFormat),
|
||||||
EndTime: a.EndTime.UTC().Format(timeMilliFormat),
|
EndTime: a.EndTime.UTC().Format(timeMilliFormat),
|
||||||
Text: a.Text,
|
Text: a.Text,
|
||||||
|
Color: a.Color,
|
||||||
Tags: a.Tags,
|
Tags: a.Tags,
|
||||||
Links: annotationLinks{
|
Links: annotationLinks{
|
||||||
Self: fmt.Sprintf("%s/%d/annotations/%s", base, src.ID, a.ID),
|
Self: fmt.Sprintf("%s/%d/annotations/%s", base, src.ID, a.ID),
|
||||||
|
@ -228,6 +230,7 @@ type newAnnotationRequest struct {
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
Text string `json:"text,omitempty"` // Text is the associated user-facing text describing the annotation
|
Text string `json:"text,omitempty"` // Text is the associated user-facing text describing the annotation
|
||||||
|
Color string `json:"color,omitempty"` // Optional annotation color
|
||||||
Tags chronograf.AnnotationTags `json:"tags"`
|
Tags chronograf.AnnotationTags `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +270,7 @@ func (ar *newAnnotationRequest) Annotation() *chronograf.Annotation {
|
||||||
StartTime: ar.StartTime,
|
StartTime: ar.StartTime,
|
||||||
EndTime: ar.EndTime,
|
EndTime: ar.EndTime,
|
||||||
Text: ar.Text,
|
Text: ar.Text,
|
||||||
|
Color: ar.Color,
|
||||||
Tags: ar.Tags,
|
Tags: ar.Tags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,6 +383,7 @@ type updateAnnotationRequest struct {
|
||||||
StartTime *time.Time `json:"startTime,omitempty"` // StartTime is the time in rfc3339 milliseconds
|
StartTime *time.Time `json:"startTime,omitempty"` // StartTime is the time in rfc3339 milliseconds
|
||||||
EndTime *time.Time `json:"endTime,omitempty"` // EndTime is the time in rfc3339 milliseconds
|
EndTime *time.Time `json:"endTime,omitempty"` // EndTime is the time in rfc3339 milliseconds
|
||||||
Text *string `json:"text,omitempty"` // Text is the associated user-facing text describing the annotation
|
Text *string `json:"text,omitempty"` // Text is the associated user-facing text describing the annotation
|
||||||
|
Color *string `json:"color,omitempty"` // Annotation color
|
||||||
Tags chronograf.AnnotationTags `json:"tags"`
|
Tags chronograf.AnnotationTags `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +484,10 @@ func (s *Service) UpdateAnnotation(w http.ResponseWriter, r *http.Request) {
|
||||||
if req.Text != nil {
|
if req.Text != nil {
|
||||||
cur.Text = *req.Text
|
cur.Text = *req.Text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.Color != nil {
|
||||||
|
cur.Color = *req.Color
|
||||||
|
}
|
||||||
if req.Tags != nil {
|
if req.Tags != nil {
|
||||||
if err = req.Tags.Valid(); err != nil {
|
if err = req.Tags.Valid(); err != nil {
|
||||||
Error(w, http.StatusBadRequest, err.Error(), s.Logger)
|
Error(w, http.StatusBadRequest, err.Error(), s.Logger)
|
||||||
|
|
|
@ -153,7 +153,52 @@ func TestService_Annotations(t *testing.T) {
|
||||||
ID: "1",
|
ID: "1",
|
||||||
w: httptest.NewRecorder(),
|
w: httptest.NewRecorder(),
|
||||||
r: httptest.NewRequest("GET", "/chronograf/v1/sources/1/annotations?since=1985-04-12T23:20:50.52Z", bytes.NewReader([]byte(`howdy`))),
|
r: httptest.NewRequest("GET", "/chronograf/v1/sources/1/annotations?since=1985-04-12T23:20:50.52Z", bytes.NewReader([]byte(`howdy`))),
|
||||||
want: `{"annotations":[{"id":"ea0aa94b-969a-4cd5-912a-5db61d502268","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"mytext","tags":{},"links":{"self":"/chronograf/v1/sources/1/annotations/ea0aa94b-969a-4cd5-912a-5db61d502268"}}]}
|
want: `{"annotations":[{"id":"ea0aa94b-969a-4cd5-912a-5db61d502268","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"mytext","color":"","tags":{},"links":{"self":"/chronograf/v1/sources/1/annotations/ea0aa94b-969a-4cd5-912a-5db61d502268"}}]}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "returns annotations with color in store",
|
||||||
|
fields: fields{
|
||||||
|
Store: mockStore,
|
||||||
|
TimeSeriesClient: &mocks.TimeSeries{
|
||||||
|
ConnectF: func(context.Context, *chronograf.Source) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
QueryF: func(context.Context, chronograf.Query) (chronograf.Response, error) {
|
||||||
|
return mocks.NewResponse(`[
|
||||||
|
{
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"name": "annotations",
|
||||||
|
"columns": [
|
||||||
|
"time",
|
||||||
|
"start_time",
|
||||||
|
"modified_time_ns",
|
||||||
|
"text",
|
||||||
|
"color",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"values": [
|
||||||
|
[
|
||||||
|
1516920177345000000,
|
||||||
|
0,
|
||||||
|
1516989242129417403,
|
||||||
|
"mytext",
|
||||||
|
"red",
|
||||||
|
"ea0aa94b-969a-4cd5-912a-5db61d502268"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]`, nil), nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ID: "1",
|
||||||
|
w: httptest.NewRecorder(),
|
||||||
|
r: httptest.NewRequest("GET", "/chronograf/v1/sources/1/annotations?since=1985-04-12T23:20:50.52Z", bytes.NewReader([]byte(`howdy`))),
|
||||||
|
want: `{"annotations":[{"id":"ea0aa94b-969a-4cd5-912a-5db61d502268","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"mytext","color":"red","tags":{},"links":{"self":"/chronograf/v1/sources/1/annotations/ea0aa94b-969a-4cd5-912a-5db61d502268"}}]}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -218,6 +263,7 @@ func TestService_UpdateAnnotation(t *testing.T) {
|
||||||
"start_time",
|
"start_time",
|
||||||
"modified_time_ns",
|
"modified_time_ns",
|
||||||
"text",
|
"text",
|
||||||
|
"color",
|
||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"values": [
|
"values": [
|
||||||
|
@ -226,6 +272,7 @@ func TestService_UpdateAnnotation(t *testing.T) {
|
||||||
0,
|
0,
|
||||||
1516989242129417403,
|
1516989242129417403,
|
||||||
"mytext",
|
"mytext",
|
||||||
|
"red",
|
||||||
"1"
|
"1"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -249,9 +296,14 @@ func TestService_UpdateAnnotation(t *testing.T) {
|
||||||
body string
|
body string
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
body: `{"id":"1","text":"newtext","color":"blue","tags":{"foo":"bar"}}`,
|
||||||
|
want: `{"id":"1","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"newtext","color":"blue","tags":{"foo":"bar"},"links":{"self":"/chronograf/v1/sources/1/annotations/1"}}
|
||||||
|
`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
body: `{"id":"1","text":"newtext","tags":{"foo":"bar"}}`,
|
body: `{"id":"1","text":"newtext","tags":{"foo":"bar"}}`,
|
||||||
want: `{"id":"1","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"newtext","tags":{"foo":"bar"},"links":{"self":"/chronograf/v1/sources/1/annotations/1"}}
|
want: `{"id":"1","startTime":"1970-01-01T00:00:00Z","endTime":"2018-01-25T22:42:57.345Z","text":"newtext","color":"red","tags":{"foo":"bar"},"links":{"self":"/chronograf/v1/sources/1/annotations/1"}}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue