mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
History and Version Control for Dashboard Updates
A simple version control system for dashboards. Closes #1504. Goals 1. To create a new dashboard version every time a dashboard is saved. 2. To allow users to view all versions of a given dashboard. 3. To allow users to rollback to a previous version of a dashboard. 4. To allow users to compare two versions of a dashboard. Usage Navigate to a dashboard, and click the settings cog. From there, click the "Changelog" button to be brought to the Changelog view. In this view, a table containing each version of a dashboard can be seen. Each entry in the table represents a dashboard version. A selectable checkbox, the version number, date created, name of the user who created that version, and commit message is shown in the table, along with a button that allows a user to restore to a previous version of that dashboard. If a user wants to restore to a previous version of their dashboard, they can do so by clicking the previously mentioned button. If a user wants to compare two different versions of a dashboard, they can do so by clicking the checkbox of two different dashboard versions, then clicking the "Compare versions" button located below the dashboard. From there, the user is brought to a view showing a summary of the dashboard differences. Each summarized change contains a link that can be clicked to take the user a JSON diff highlighting the changes line by line. Overview of Changes Backend Changes - A `dashboard_version` table was created to store each dashboard version, along with a dashboard version model and structs to represent the queries and commands necessary for the dashboard version API methods. - API endpoints were created to support working with dashboard versions. - Methods were added to create, update, read, and destroy dashboard versions in the database. - Logic was added to compute the diff between two versions, and display it to the user. - The dashboard migration logic was updated to save a "Version 1" of each existing dashboard in the database. Frontend Changes - New views - Methods to pull JSON and HTML from endpoints New API Endpoints Each endpoint requires the authorization header to be sent in the format, ``` Authorization: Bearer <jwt> ``` where `<jwt>` is a JSON web token obtained from the Grafana admin panel. `GET "/api/dashboards/db/:dashboardId/versions?orderBy=<string>&limit=<int>&start=<int>"` Get all dashboard versions for the given dashboard ID. Accepts three URL parameters: - `orderBy` String to order the results by. Possible values are `version`, `created`, `created_by`, `message`. Default is `versions`. Ordering is always in descending order. - `limit` Maximum number of results to return - `start` Position in results to start from `GET "/api/dashboards/db/:dashboardId/versions/:id"` Get an individual dashboard version by ID, for the given dashboard ID. `POST "/api/dashboards/db/:dashboardId/restore"` Restore to the given dashboard version. Post body is of content-type `application/json`, and must contain. ```json { "dashboardId": <int>, "version": <int> } ``` `GET "/api/dashboards/db/:dashboardId/compare/:versionA...:versionB"` Compare two dashboard versions by ID for the given dashboard ID, returning a JSON delta formatted representation of the diff. The URL format follows what GitHub does. For example, visiting [/api/dashboards/db/18/compare/22...33](http://ec2-54-80-139-44.compute-1.amazonaws.com:3000/api/dashboards/db/18/compare/22...33) will return the diff between versions 22 and 33 for the dashboard ID 18. Dependencies Added - The Go package [gojsondiff](https://github.com/yudai/gojsondiff) was added and vendored.
This commit is contained in:
committed by
Carlos Rosquillas
parent
59f3cca135
commit
b6e46c9eb8
76
public/app/core/directives/diff-view.ts
Normal file
76
public/app/core/directives/diff-view.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import coreModule from '../core_module';
|
||||
|
||||
export class DeltaCtrl {
|
||||
observer: any;
|
||||
|
||||
constructor(private $rootScope) {
|
||||
const waitForCompile = function(mutations) {
|
||||
if (mutations.length === 1) {
|
||||
this.$rootScope.appEvent('json-diff-ready');
|
||||
}
|
||||
};
|
||||
|
||||
this.observer = new MutationObserver(waitForCompile.bind(this));
|
||||
|
||||
const observerConfig = {
|
||||
attributes: true,
|
||||
attributeFilter: ['class'],
|
||||
characterData: false,
|
||||
childList: true,
|
||||
subtree: false,
|
||||
};
|
||||
|
||||
this.observer.observe(angular.element('.delta-html')[0], observerConfig);
|
||||
}
|
||||
|
||||
$onDestroy() {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
export function delta() {
|
||||
return {
|
||||
controller: DeltaCtrl,
|
||||
replace: false,
|
||||
restrict: 'A',
|
||||
};
|
||||
}
|
||||
coreModule.directive('diffDelta', delta);
|
||||
|
||||
// Link to JSON line number
|
||||
export class LinkJSONCtrl {
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private $anchorScroll) {}
|
||||
|
||||
goToLine(line: number) {
|
||||
let unbind;
|
||||
|
||||
const scroll = () => {
|
||||
this.$anchorScroll(`l${line}`);
|
||||
unbind();
|
||||
};
|
||||
|
||||
this.$scope.switchView().then(() => {
|
||||
unbind = this.$rootScope.$on('json-diff-ready', scroll.bind(this));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function linkJson() {
|
||||
return {
|
||||
controller: LinkJSONCtrl,
|
||||
controllerAs: 'ctrl',
|
||||
replace: true,
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
line: '@lineDisplay',
|
||||
link: '@lineLink',
|
||||
switchView: '&',
|
||||
},
|
||||
templateUrl: 'public/app/features/dashboard/audit/partials/link-json.html',
|
||||
};
|
||||
}
|
||||
coreModule.directive('diffLinkJson', linkJson);
|
||||
Reference in New Issue
Block a user