mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 05:29:42 -06:00
b6e46c9eb8
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.
331 lines
8.9 KiB
SCSS
331 lines
8.9 KiB
SCSS
// Cosmo 2.3.2
|
|
// Variables
|
|
// --------------------------------------------------
|
|
|
|
|
|
// Global values
|
|
// --------------------------------------------------
|
|
|
|
|
|
// Grays
|
|
// -------------------------
|
|
$black: #000;
|
|
|
|
// -------------------------
|
|
$black: #000;
|
|
$dark-1: #141414;
|
|
$dark-2: #1f1d1d;
|
|
$dark-3: #292929;
|
|
$dark-4: #373737;
|
|
$dark-5: #444444;
|
|
$gray-1: #555555;
|
|
$gray-2: #7B7B7B;
|
|
$gray-3: #b3b3b3;
|
|
$gray-4: #D8D9DA;
|
|
$gray-5: #ECECEC;
|
|
$gray-6: #f4f5f8;
|
|
$gray-7: #fbfbfb;
|
|
|
|
$white: #fff;
|
|
|
|
// Accent colors
|
|
// -------------------------
|
|
$blue: #2AB2E4;
|
|
$blue-dark: #3CAAD6;
|
|
$green: #28B62C;
|
|
$red: #FF4136;
|
|
$yellow: #FF851B;
|
|
$orange: #Ff7941;
|
|
$pink: #E671B8;
|
|
$purple: #9954BB;
|
|
$variable: #2AB2E4;
|
|
|
|
$brand-primary: $orange;
|
|
$brand-success: $green;
|
|
$brand-warning: $orange;
|
|
$brand-danger: $red;
|
|
|
|
// Status colors
|
|
// -------------------------
|
|
$online: #01A64F;
|
|
$warn: #F79520;
|
|
$critical: #EC2128;
|
|
|
|
// Scaffolding
|
|
// -------------------------
|
|
|
|
$body-bg: $white;
|
|
$page-bg: $white;
|
|
$body-color: $gray-1;
|
|
$text-color: $gray-1;
|
|
$text-color-strong: $white;
|
|
$text-color-weak: $gray-3;
|
|
$text-color-faint: $gray-4;
|
|
$text-color-emphasis: $dark-5;
|
|
|
|
$text-shadow-strong: none;
|
|
$text-shadow-faint: none;
|
|
|
|
// gradients
|
|
$brand-gradient: linear-gradient(to right, rgba(255,213,0,1.0) 0%, rgba(255,68,0,1.0) 99%, rgba(255,68,0,1.0) 100%);
|
|
$page-gradient: linear-gradient(60deg, transparent 70%, darken($page-bg, 4%) 98%);
|
|
|
|
// Links
|
|
// -------------------------
|
|
$link-color: $gray-1;
|
|
$link-color-disabled: lighten($link-color, 30%);
|
|
$link-hover-color: darken($link-color, 20%);
|
|
$external-link-color: $blue;
|
|
|
|
// Typography
|
|
// -------------------------
|
|
$headings-color: $text-color;
|
|
$abbr-border-color: $gray-2 !default;
|
|
$text-muted: $text-color-weak;
|
|
|
|
$blockquote-small-color: $gray-2 !default;
|
|
$blockquote-border-color: $gray-3 !default;
|
|
|
|
$hr-border-color: $dark-3 !default;
|
|
|
|
// Components
|
|
$component-active-color: $white !default;
|
|
$component-active-bg: $brand-primary !default;
|
|
|
|
// Panel
|
|
// -------------------------
|
|
|
|
$panel-bg: $gray-7;
|
|
$panel-border: solid 1px $gray-6;
|
|
$panel-drop-zone-bg: repeating-linear-gradient(-128deg, $body-bg, $body-bg 10px, $gray-6 10px, $gray-6 20px);
|
|
$panel-menu-border: solid 1px white;
|
|
|
|
$divider-border-color: $gray-2;
|
|
|
|
// Graphite Target Editor
|
|
$tight-form-border: $gray-4;
|
|
$tight-form-bg: $gray-6;
|
|
|
|
$tight-form-func-bg: $gray-5;
|
|
$tight-form-func-highlight-bg: $gray-6;
|
|
|
|
$modal-background: $body-bg;
|
|
$code-tag-bg: $gray-6;
|
|
$code-tag-border: darken($code-tag-bg, 3%);
|
|
|
|
// Lists
|
|
$grafanaListBackground: $gray-6;
|
|
$grafanaListAccent: $gray-5;
|
|
$grafanaListBorderTop: $gray-3;
|
|
$grafanaListBorderBottom: $gray-3;
|
|
$grafanaListHighlight: $gray-5;
|
|
$grafanaListMainLinkColor: $text-color;
|
|
|
|
|
|
// Tables
|
|
// -------------------------
|
|
$table-bg: transparent; // overall background-color
|
|
$table-bg-accent: $gray-5; // for striping
|
|
$table-bg-hover: $gray-5; // for hover
|
|
$table-bg-active: $table-bg-hover !default;
|
|
$table-border: $gray-3; // table and cell border
|
|
|
|
// Scrollbars
|
|
$scrollbarBackground: $gray-5;
|
|
$scrollbarBackground2: $gray-5;
|
|
$scrollbarBorder: $gray-4;
|
|
|
|
// Buttons
|
|
// -------------------------
|
|
$btn-primary-bg: $brand-primary;
|
|
$btn-primary-bg-hl: lighten($brand-primary, 8%);
|
|
|
|
$btn-secondary-bg: $blue-dark;
|
|
$btn-secondary-bg-hl: lighten($blue-dark, 4%);
|
|
|
|
$btn-success-bg: lighten($green, 3%);
|
|
$btn-success-bg-hl: darken($green, 3%);
|
|
|
|
$btn-warning-bg: lighten($orange, 3%);
|
|
$btn-warning-bg-hl: darken($orange, 3%);
|
|
|
|
$btn-danger-bg: lighten($red, 3%);
|
|
$btn-danger-bg-hl: darken($red, 3%);
|
|
|
|
$btn-inverse-bg: $gray-5;
|
|
$btn-inverse-bg-hl: darken($gray-5, 5%);
|
|
$btn-inverse-text-color: $dark-4;
|
|
|
|
$btn-link-color: $gray-1;
|
|
|
|
$btn-divider-left: $gray-4;
|
|
$btn-divider-right: $gray-7;
|
|
$btn-drag-image: '../img/grab_light.svg';
|
|
|
|
$iconContainerBackground: $white;
|
|
|
|
// Forms
|
|
// -------------------------
|
|
$input-bg: $gray-7;
|
|
$input-bg-disabled: $gray-5;
|
|
|
|
$input-color: $dark-3;
|
|
$input-border-color: $gray-5;
|
|
$input-box-shadow: none;
|
|
$input-border-focus: $blue !default;
|
|
$input-box-shadow-focus: $blue !default;
|
|
$input-color-placeholder: $gray-4 !default;
|
|
$input-label-bg: $gray-6;
|
|
$input-invalid-border-color: lighten($red, 5%);
|
|
|
|
// Sidemenu
|
|
// -------------------------
|
|
$side-menu-bg: $body-bg;
|
|
$side-menu-item-hover-bg: $gray-6;
|
|
$side-menu-opacity: 0.97;
|
|
|
|
// search
|
|
$search-shadow: 0 5px 30px 0 lighten($gray-2, 30%);
|
|
|
|
// Dropdowns
|
|
// -------------------------
|
|
$dropdownBackground: $white;
|
|
$dropdownBorder: $tight-form-border;
|
|
$dropdownDividerTop: $gray-6;
|
|
$dropdownDividerBottom: $white;
|
|
$dropdownDivider: $dropdownDividerTop;
|
|
$dropdownTitle: $gray-3;
|
|
|
|
$dropdownLinkColor: $dark-3;
|
|
$dropdownLinkColorHover: $link-color;
|
|
$dropdownLinkColorActive: $link-color;
|
|
|
|
$dropdownLinkBackgroundActive: $gray-6;
|
|
$dropdownLinkBackgroundHover: $gray-6;
|
|
|
|
|
|
// COMPONENT VARIABLES
|
|
// --------------------------------------------------
|
|
|
|
|
|
// Input placeholder text color
|
|
// -------------------------
|
|
$placeholderText: $gray-2;
|
|
|
|
|
|
// Hr border color
|
|
// -------------------------
|
|
$hrBorder: $gray-3;
|
|
|
|
|
|
// Horizontal forms & lists
|
|
// -------------------------
|
|
$horizontalComponentOffset: 180px;
|
|
|
|
|
|
// Wells
|
|
// -------------------------
|
|
$wellBackground: $gray-3;
|
|
|
|
|
|
// Navbar
|
|
// -------------------------
|
|
|
|
$navbarHeight: 52px;
|
|
$navbarBackgroundHighlight: #f8f8f8;
|
|
$navbarBackground: #f8f8f8;
|
|
$navbarBorder: 1px solid $tight-form-border;
|
|
|
|
$navbarText: #666;
|
|
$navbarLinkColor: #666;
|
|
$navbarLinkColorHover: #333;
|
|
$navbarLinkColorActive: #555;
|
|
$navbarLinkBackgroundHover: transparent;
|
|
$navbarLinkBackgroundActive: darken($navbarBackground, 6.5%);
|
|
$navbarDropdownShadow: inset 0px 4px 7px -4px darken($body-bg, 20%);
|
|
|
|
$navbarBrandColor: $navbarLinkColor;
|
|
|
|
$navbarButtonBackground: lighten($navbarBackground, 3%);
|
|
$navbarButtonBackgroundHighlight: lighten($navbarBackground, 5%);
|
|
|
|
|
|
// Pagination
|
|
// -------------------------
|
|
$paginationBackground: $gray-2;
|
|
$paginationBorder: transparent;
|
|
$paginationActiveBackground: $blue;
|
|
|
|
|
|
// Form states and alerts
|
|
// -------------------------
|
|
$state-warning-text: lighten($orange, 10%);
|
|
$state-warning-bg: $orange;
|
|
$warningBorder: transparent;
|
|
|
|
$errorText: lighten($red, 10%);
|
|
$errorBackground: $red;
|
|
$errorBorder: transparent;
|
|
|
|
$successText: lighten($green, 10%);
|
|
$successBackground: $green;
|
|
$successBorder: transparent;
|
|
|
|
$infoText: $blue;
|
|
$infoBackground: $blue-dark;
|
|
$infoBorder: transparent;
|
|
|
|
// popover
|
|
$popover-bg: $gray-5;
|
|
$popover-color: $text-color;
|
|
$popover-border-color: $gray-3;
|
|
|
|
$popover-help-bg: $blue-dark;
|
|
$popover-help-color: $gray-6;
|
|
|
|
// Tooltips and popovers
|
|
// -------------------------
|
|
$tooltipColor: $popover-help-color;
|
|
$tooltipBackground: $popover-help-bg;
|
|
$tooltipArrowWidth: 5px;
|
|
$tooltipArrowColor: $tooltipBackground;
|
|
$tooltipLinkColor: lighten($popover-help-color, 5%);
|
|
$graph-tooltip-bg: $gray-5;
|
|
|
|
// images
|
|
$checkboxImageUrl: '../img/checkbox_white.png';
|
|
|
|
// cards
|
|
$card-background: linear-gradient(135deg, $gray-5, $gray-6);
|
|
$card-background-hover: linear-gradient(135deg, $gray-6, $gray-7);
|
|
$card-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, .1), 1px 1px 0 0 rgba(0, 0, 0, .1);
|
|
|
|
// footer
|
|
$footer-link-color: $gray-3;
|
|
$footer-link-hover: $dark-5;
|
|
|
|
|
|
// Changelog and diff
|
|
// -------------------------
|
|
$diff-label-bg: $gray-5;
|
|
$diff-label-fg: $gray-2;
|
|
|
|
$diff-switch-bg: $gray-7;
|
|
$diff-switch-disabled: $gray-5;
|
|
|
|
$diff-arrow-color: $dark-3;
|
|
$diff-group-bg: $gray-7;
|
|
|
|
$diff-json-bg: $gray-5;
|
|
$diff-json-fg: $gray-2;
|
|
|
|
$diff-json-added: lighten(desaturate($green, 30%), 10%);
|
|
$diff-json-deleted: desaturate($red, 35%);
|
|
|
|
$diff-json-old: #5a372a;
|
|
$diff-json-new: #664e33;
|
|
|
|
$diff-json-changed-fg: $gray-6;
|
|
$diff-json-changed-num: $gray-4;
|
|
$diff-json-icon: $gray-4;
|