mirror of
https://github.com/grafana/grafana.git
synced 2025-01-15 19:22:34 -06:00
create annotations work
This commit is contained in:
parent
2fce88ee62
commit
dbe5480edc
@ -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>
|
||||
|
@ -1,56 +0,0 @@
|
||||
///<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
|
||||
|
Loading…
Reference in New Issue
Block a user