Commit dbe5480e by Torkel Ödegaard

create annotations work

parent 2fce88ee
......@@ -75,7 +75,7 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response
}
item.Id = 0
item.Epoch = cmd.EndTime
item.Epoch = cmd.TimeEnd
if err := repo.Save(&item); err != nil {
return ApiError(500, "Failed save annotation for region end time", err)
......
......@@ -27,7 +27,7 @@ type PostAnnotationsCmd struct {
FillColor string `json:"fillColor"`
IsRegion bool `json:"isRegion"`
EndTime int64 `json:"endTime"`
TimeEnd int64 `json:"timeEnd"`
}
type DeleteAnnotationsCmd struct {
......
......@@ -7,41 +7,49 @@ import coreModule from 'app/core/core_module';
import Drop from 'tether-drop';
/** @ngInject **/
function popoverSrv($compile, $rootScope) {
function popoverSrv($compile, $rootScope, $timeout) {
let openDrop = null;
this.close = function() {
if (openDrop) {
openDrop.close();
}
};
this.show = function(options) {
var classNames = 'drop-popover';
var popoverScope = _.extend($rootScope.$new(true), options.model);
if (openDrop) {
openDrop.close();
}
var scope = _.extend($rootScope.$new(true), options.model);
var drop;
if (options.classNames) {
classNames = options.classNames;
}
var cleanUp = () => {
setTimeout(() => {
scope.$destroy();
drop.destroy();
function destroyDrop() {
setTimeout(function() {
if (drop.tether) {
drop.destroy();
if (options.onClose) {
options.onClose();
}
});
}
};
popoverScope.dismiss = function() {
popoverScope.$destroy();
destroyDrop();
scope.dismiss = () => {
drop.close();
};
var contentElement = document.createElement('div');
contentElement.innerHTML = options.template;
$compile(contentElement)(popoverScope);
$compile(contentElement)(scope);
drop = new Drop({
target: options.element,
content: contentElement,
position: options.position,
classes: classNames,
openOn: options.openOn || 'hover',
classes: options.classNames || 'drop-popover',
openOn: options.openOn,
hoverCloseDelay: 200,
tetherOptions: {
constraints: [{to: 'scrollParent', attachment: "none both"}]
......@@ -49,14 +57,11 @@ function popoverSrv($compile, $rootScope) {
});
drop.on('close', () => {
popoverScope.dismiss({fromDropClose: true});
destroyDrop();
if (options.onClose) {
options.onClose();
}
cleanUp();
});
setTimeout(() => { drop.open(); }, 10);
openDrop = drop;
$timeout(() => { drop.open(); }, 10);
};
}
......
......@@ -35,6 +35,7 @@ export class AnnotationsSrv {
// combine the annotations and flatten results
var annotations = _.flattenDeep([results[0], results[1]]);
// filter out annotations that do not belong to requesting panel
annotations = _.filter(annotations, item => {
if (item.panelId && options.panel.id !== item.panelId) {
......@@ -60,7 +61,7 @@ export class AnnotationsSrv {
var panel = options.panel;
var dashboard = options.dashboard;
if (panel) {
if (panel && panel.alert) {
return this.backendSrv.get('/api/annotations', {
from: options.range.from.valueOf(),
to: options.range.to.valueOf(),
......@@ -133,7 +134,7 @@ export class AnnotationsSrv {
return this.globalAnnotationsPromise;
}
postAnnotation(annotation) {
saveAnnotationEvent(annotation) {
return this.backendSrv.post('/api/annotations', annotation);
}
......
......@@ -5,11 +5,11 @@ import moment from 'moment';
import coreModule from 'app/core/core_module';
import {MetricsPanelCtrl} from 'app/plugins/sdk';
export class AnnotationItem {
export class AnnotationEvent {
dashboardId: number;
panelId: number;
time: Date;
timeEnd: Date;
time: any;
timeEnd: any;
isRegion: boolean;
title: string;
text: string;
......@@ -17,14 +17,13 @@ export class AnnotationItem {
export class EventEditorCtrl {
panelCtrl: MetricsPanelCtrl;
timeFormat = 'YYYY-MM-DD HH:mm:ss';
annotation: AnnotationItem;
annotation: AnnotationEvent;
timeRange: {from: number, to: number};
form: any;
/** @ngInject **/
constructor() {
this.annotation = new AnnotationItem();
constructor(private annotationsSrv) {
this.annotation = new AnnotationEvent();
this.annotation.panelId = this.panelCtrl.panel.id;
this.annotation.dashboardId = this.panelCtrl.dashboard.id;
this.annotation.text = "hello";
......@@ -40,6 +39,19 @@ export class EventEditorCtrl {
if (!this.form.$valid) {
return;
}
let saveModel = _.cloneDeep(this.annotation);
saveModel.time = saveModel.time.valueOf();
if (saveModel.isRegion) {
saveModel.timeEnd = saveModel.timeEnd.valueOf();
}
if (saveModel.timeEnd < saveModel.time) {
console.log('invalid time');
return;
}
this.annotationsSrv.saveAnnotationEvent(saveModel);
}
}
......@@ -52,7 +64,8 @@ export function eventEditor() {
templateUrl: 'public/app/features/annotations/partials/event_editor.html',
scope: {
"panelCtrl": "=",
"timeRange": "="
"timeRange": "=",
"cancel": "&",
}
};
}
......
......@@ -9,31 +9,30 @@
</div>
<!-- single event -->
<div ng-if="!ctrl.annotation.isRegion">
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-7">Time</span>
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
</div>
</div>
</div>
<!-- region event -->
<div ng-if="ctrl.annotation.isRegion">
<div class="gf-form">
<span class="gf-form-label width-7">Start</span>
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
</div>
<div class="gf-form">
<span class="gf-form-label width-7">End</span>
<input type="text" ng-model="ctrl.annotation.timeEnd" class="gf-form-input max-width-20" input-datetime required>
</div>
</div>
<div class="gf-form gf-form--v-stretch">
<span class="gf-form-label width-7">Description</span>
<textarea class="gf-form-input width-20" rows="3" ng-model="ctrl.annotation.text" placeholder="Event description"></textarea>
</div>
<div class="gf-form">
<span class="gf-form-label width-7">Time</span>
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
</div>
</div>
<!-- region event -->
<div ng-if="ctrl.annotation.isRegion">
<div class="gf-form">
<span class="gf-form-label width-7">Start</span>
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
</div>
<div class="gf-form">
<span class="gf-form-label width-7">End</span>
<input type="text" ng-model="ctrl.annotation.timeEnd" class="gf-form-input max-width-20" input-datetime required>
</div>
</div>
<div class="gf-form gf-form--v-stretch">
<span class="gf-form-label width-7">Description</span>
<textarea class="gf-form-input width-20" rows="3" ng-model="ctrl.annotation.text" placeholder="Event description"></textarea>
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn gf-form-btn btn-success" ng-click="ctrl.save()">Save</button>
</div>
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn gf-form-btn btn-success" ng-click="ctrl.save()">Save</button>
<a class="btn-text" ng-click="ctrl.cancel();">Cancel</a>
</div>
</div>
</form>
///<reference path="../../headers/common.d.ts" />
import angular from 'angular';
import moment from 'moment';
export class AddAnnotationModalCtrl {
timeFormat = 'YYYY-MM-DD HH:mm:ss';
annotation: any;
graphCtrl: any;
/** @ngInject */
constructor(private $scope) {
this.graphCtrl = $scope.ctrl;
$scope.ctrl = this;
let dashboardId = this.graphCtrl.dashboard.id;
let panelId = this.graphCtrl.panel.id;
this.annotation = {
dashboardId: dashboardId,
panelId: panelId,
time: null,
timeTo: null,
title: "",
text: ""
};
this.annotation.time = moment($scope.annotationTimeRange.from).format(this.timeFormat);0
if ($scope.annotationTimeRange.to) {
this.annotation.timeTo = moment($scope.annotationTimeRange.to).format(this.timeFormat);
}
}
addAnnotation() {
this.annotation.time = moment(this.annotation.time, this.timeFormat).valueOf();
if (this.annotation.timeTo) {
this.annotation.timeTo = moment(this.annotation.timeTo, this.timeFormat).valueOf();
}
this.graphCtrl.pushAnnotation(this.annotation)
.then(response => {
this.close();
})
.catch(error => {
console.log(error);
this.close();
});
}
close() {
this.$scope.dismiss();
}
}
angular
.module('grafana.controllers')
.controller('AddAnnotationModalCtrl', AddAnnotationModalCtrl);
......@@ -84,8 +84,8 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
element: elem[0],
classNames: 'drop-popover drop-popover--form',
position: 'bottom center',
openOn: 'click',
template: '<event-editor panel-ctrl="panelCtrl" time-range="timeRange"></event-editor>',
openOn: null,
template: '<event-editor panel-ctrl="panelCtrl" time-range="timeRange" cancel="dismiss()"></event-editor>',
model: {
timeRange: timeRange,
panelCtrl: ctrl,
......
......@@ -48,6 +48,7 @@ function (angular, _, $) {
element: el[0],
position: 'bottom center',
template: '<gf-color-picker></gf-color-picker>',
openOn: 'hover',
model: {
series: series,
toggleAxis: function() {
......
......@@ -67,7 +67,6 @@
.modal-content {
padding: $spacer*2;
min-height: $spacer*15;
}
// Remove bottom margin if need be
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment