Compare commits

...

24 Commits

Author SHA1 Message Date
Torkel Ödegaard
de8f6ac4b1 Bumped version to 6.1.2 2019-04-08 11:16:37 +02:00
Patrick O'Carroll
0c7d43b999 Graph: Fixed series legend color for hidden series (#16438)
* replaced colors for headingColor, link and linkDisabled with colors from grayscale, replaced colors for linkDisabled and linkHover with colors from grayscale, changed color for sha-modal-in-text to text-color-empahises

* fixed snapshot

(cherry picked from commit 70dcb6a22a)
2019-04-08 11:15:58 +02:00
Torkel Ödegaard
0974663079 Styles: Fixed left menu highlight (#16431)
Upgrades to webpack & css optimization caused changes
in production build that removed the left brand
gradient.

Fixes #16430

(cherry picked from commit 0968fbed49)
2019-04-08 11:15:51 +02:00
Torkel Ödegaard
9eba279b8d Graph: Fixed tooltip highlight on white theme (#16429)
Fixes #16359

(cherry picked from commit 9b39dbc2fb)
2019-04-08 11:15:41 +02:00
Torkel Ödegaard
da0302f15e Units: Correctly use the override decimals (#16413)
Fixes bugs introduced in PR #14716 and #15146 also restores unit tests that where lost in the
move from kbn units to @grafana/ui units

Fixes #16068
Fixes #16373

(cherry picked from commit 8a4a6b4dc1)
2019-04-08 11:15:31 +02:00
Torkel Ödegaard
eff01d2b54 Updated version to 6.1.1 2019-04-05 11:42:24 +02:00
Torkel Ödegaard
cbc515b22c Fix: Graphite query rendering fix (#16390)
Only interpolate string parameters

Fixes #16367

(cherry picked from commit 173e7fd839)
2019-04-05 11:42:03 +02:00
Torkel Ödegaard
638d49dd6e Fix: align panel padding between sass & js theme (#16404)
(cherry picked from commit 35e68b868e)
2019-04-05 11:37:24 +02:00
Torkel Ödegaard
9d452256bf Fix: playlist now preserve the correct url query params (#16403)
Fixes #16377

(cherry picked from commit 6d3b6f3c2f)
2019-04-05 11:37:15 +02:00
Sean Lafferty
f941f25831 Fix: Query editor toggle edit mode fix (#16394)
Increase timeout when waiting for datasource toggleEditorMode check 

Fixes  #16393

(cherry picked from commit c2d399b059)
2019-04-05 11:37:07 +02:00
Marcus Efraimsson
b585fdec6f Alerting: Notification channel http api fixes (#16379)
Fixes so it's possible to create new notification channel and providing uid.
Fixes better error/result handling when updating a notifcation channel.

Fixes #16372
Ref #16219 #16012

(cherry picked from commit 5da1faf454)
2019-04-05 11:36:58 +02:00
Leonard Gram
e6c639f6f0 build: Fixed incorrect permissions for repo folders in ci-deploy. (#16360)
(cherry picked from commit 6baba64935)
2019-04-05 11:36:51 +02:00
Torkel Ödegaard
03346b6f6f Build: updated version to 6.1.0 2019-04-03 10:08:03 +02:00
Mitsuhiro Tanda
9a575f93ad Fix: Cloudwatch fix for dimension value (#16356)
Fixes autocomplete suggestion after changing dimension key

Fixes #15984

(cherry picked from commit 58eb74660d)
2019-04-03 09:57:28 +02:00
Torkel Ödegaard
21957ad515 Fix: Autoprefixer is now working (#16351)
The autoprefixer not working broke the phantomjs backend png rendering

Fixes #16345

(cherry picked from commit 2e59166daa)
2019-04-03 09:57:16 +02:00
Leonard Gram
bd93aad63d build: Fix for renamed package for armv6.
(cherry picked from commit b48c18a1c5)
2019-04-03 09:57:07 +02:00
Torkel Ödegaard
8ae5980c23 Fix: Graphite query ast to string fix (#16297)
Fixes #16291

(cherry picked from commit 74ae756d02)
2019-04-03 09:56:55 +02:00
Torkel Ödegaard
eb38581dc1 Fix: Template query editor this bind exception fix (#16299)
Also fixes the default 100% width of inputs.
Fixes #16298

(cherry picked from commit 5c3a0a624a)
2019-04-03 09:56:43 +02:00
Marcus Efraimsson
be217d8c0e Fix: Alerting Notification channel http api fixes (#16288)
Fix so that uid can be changed when updating notification
channels through the http api.
Update documentation

(cherry picked from commit 79b86466fd)
2019-04-03 09:56:11 +02:00
Floyd May
dfbc3bfb1f InfluxDB: Fix tag names with periods in alerting (#16255)
Updates regex to match tag names with periods when generating
series names in alerting evaluation (backend).

Fixes #9148

(cherry picked from commit 33d1d427bc)
2019-04-03 09:56:01 +02:00
Torkel Ödegaard
a6c8cd7f3a Automation: Updates to yarn cli cherrypick & changelog tasks (#16357)
* Automation: Updated cherrypick task to show merge sha

* Fixed changelog milestone filtering

(cherry picked from commit 5aea77fc95)
2019-04-03 09:55:19 +02:00
Daniel Lee
56e4032db3 Chore: docs whats new article for the 6.1 release (#16251)
(cherry picked from commit 0e2d279e3a)
2019-03-27 13:49:01 +01:00
Daniel Lee
944e526eb9 release 6.1.0-beta1 2019-03-27 12:06:23 +01:00
Daniel Lee
0d6db7e6b8 Chore: scripts update publish script before 6.1 release
(cherry picked from commit cbe2543717894ace2a8347859bff22dfbbf57a73)
2019-03-27 12:02:59 +01:00
46 changed files with 277 additions and 109 deletions

4
.browserslistrc Normal file
View File

@@ -0,0 +1,4 @@
>1%,
Chrome > 20
last 4 versions,
Firefox ESR

View File

@@ -322,7 +322,7 @@ jobs:
deploy-enterprise-master:
docker:
- image: grafana/grafana-ci-deploy:1.2.1
- image: grafana/grafana-ci-deploy:1.2.2
steps:
- attach_workspace:
at: .
@@ -347,7 +347,7 @@ jobs:
deploy-enterprise-release:
docker:
- image: grafana/grafana-ci-deploy:1.2.1
- image: grafana/grafana-ci-deploy:1.2.2
steps:
- checkout
- attach_workspace:
@@ -380,7 +380,7 @@ jobs:
deploy-master:
docker:
- image: grafana/grafana-ci-deploy:1.2.1
- image: grafana/grafana-ci-deploy:1.2.2
steps:
- attach_workspace:
at: .
@@ -411,7 +411,7 @@ jobs:
deploy-release:
docker:
- image: grafana/grafana-ci-deploy:1.2.1
- image: grafana/grafana-ci-deploy:1.2.2
steps:
- checkout
- attach_workspace:

View File

@@ -361,6 +361,7 @@ func createPackage(options linuxPackageOptions) {
fmt.Printf("pkgArch is set to '%s', generated arch is '%s'\n", pkgArch, options.packageArch)
if pkgArch == "armv6" {
name += "-rpi"
args = append(args, "--replaces", "grafana")
}
args = append(args, "--name", name)

View File

@@ -0,0 +1,55 @@
+++
title = "What's New in Grafana v6.1"
description = "Feature & improvement highlights for Grafana v6.1"
keywords = ["grafana", "new", "documentation", "6.1"]
type = "docs"
[menu.docs]
name = "Version 6.1"
identifier = "v6.1"
parent = "whatsnew"
weight = -12
+++
# What's New in Grafana v6.1
## Highlights
### Ad hoc Filtering for Prometheus
{{< imgbox max-width="30%" img="/img/docs/v61/prometheus-ad-hoc.gif" caption="Ad-hoc filters variable for Prometheus" >}}
The ad hoc filter feature allows you to create new key/value filters on the fly with autocomplete for both key and values. The filter condition is then automatically applied to all queries on the dashboard. This makes it easier to explore your data in a dashboard without changing queries and without having to add new template variables.
Other timeseries databases with label-based query languages have had this feature for a while. Recently Prometheus added support for fetching label names from their API and thanks to [Mitsuhiro Tanda](https://github.com/mtanda) implementing it in Grafana, the Prometheus datasource finally supports ad hoc filtering.
Support for fetching a list of label names was released in Prometheus v2.6.0 so that is a requirement for this feature to work in Grafana.
### Permissions: Editors can own dashboards, folders and teams they create
When the dashboard folders feature and permissions system was released in Grafana 5.0, users with the editor role were not allowed to administrate dashboards, folders or teams. In the 6.1 release, we have added a config option so that by default editors are admins for any Dashboard, Folder or Team they create.
This feature also adds a new Team permission that can be assigned to any user with the editor or viewer role and lets that user add other users to the Team.
We believe that this is more in line with the Grafana philosophy, as it will allow teams to be more self-organizing. This option will be made permanent if it gets positive feedback from the community so let us know what you think in the [issue on GitHub](https://github.com/grafana/grafana/issues/15590).
To turn this feature on add the following [config option](/installation/configuration/#editors-can-admin) to your Grafana ini file in the `users` section and then restart the Grafana server:
```ini
[users]
editors_can_admin = true
```
### Minor Features and Fixes
This release contains a lot of small features and fixes:
- A new keyboard shortcut `d l` toggles all Graph legends in a dashboard.
- A small bug fix for Elasticsearch - template variables in the alias field now work properly.
- Some new capabilities have been added for datasource plugins that will be of interest to plugin authors:
- a new oauth pass-through option.
- it is now possible to add user details to requests sent to the dataproxy.
- Heatmap and Explore fixes.
Checkout the [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md) file for a complete list of new features, changes, and bug fixes.
A huge thanks to our community for all the reported issues, bug fixes and feedback.

View File

@@ -152,6 +152,7 @@ Content-Type: application/json
PUT /api/alert-notifications/1 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
@@ -170,7 +171,7 @@ Content-Type: application/json
Deletes an existing notification channel identified by uid.
**Example Request**:
**Example Request**:
```http
DELETE /api/alert-notifications/uid/team-a-email-notifier HTTP/1.1
Accept: application/json
@@ -198,6 +199,7 @@ Content-Type: application/json
DELETE /api/alert-notifications/1 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
@@ -217,7 +219,7 @@ Content-Type: application/json
**Example Request**:
**Example Request**:
```http
POST /api/alert-notifications/test HTTP/1.1
Accept: application/json
Content-Type: application/json
@@ -247,7 +249,7 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"id": 1,
"uid": "cIBgcSjkk",
"uid": "new-alert-notification", // optional
"name": "new alert notification", //Required
"type": "email", //Required
"isDefault": false,
@@ -267,7 +269,7 @@ Content-Type: application/json
{
"id": 1,
"uid": "cIBgcSjkk",
"uid": "new-alert-notification",
"name": "new alert notification",
"type": "email",
"isDefault": false,

View File

@@ -5,7 +5,7 @@
"company": "Grafana Labs"
},
"name": "grafana",
"version": "6.1.0-pre",
"version": "6.1.2",
"repository": {
"type": "git",
"url": "http://github.com/grafana/grafana.git"

View File

@@ -72,7 +72,7 @@ export class Input extends PureComponent<Props> {
const inputElementProps = this.populateEventPropsWithStatus(restProps, validationEvents);
return (
<div>
<div style={{ flexGrow: 1 }}>
<input {...inputElementProps} className={inputClassName} />
{error && !hideErrorMessage && <span>{error}</span>}
</div>

View File

@@ -1,7 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Input renders correctly 1`] = `
<div>
<div
style={
Object {
"flexGrow": 1,
}
}
>
<input
className="gf-form-input"
/>

View File

@@ -148,10 +148,10 @@ exports[`Render should render with base threshold 1`] = `
"grayBlue": "#212327",
"greenBase": "#299c46",
"greenShade": "#23843b",
"headingColor": "#e3e3e3",
"headingColor": "#d8d9da",
"inputBlack": "#09090b",
"link": "#e3e3e3",
"linkDisabled": "#e3e3e3",
"link": "#d8d9da",
"linkDisabled": "#8e8e8e",
"linkExternal": "#33b5e5",
"linkHover": "#ffffff",
"online": "#299c46",
@@ -178,8 +178,8 @@ exports[`Render should render with base threshold 1`] = `
},
"name": "Grafana Dark",
"panelPadding": Object {
"horizontal": 10,
"vertical": 5,
"horizontal": 16,
"vertical": 8,
},
"spacing": Object {
"d": "14px",
@@ -305,10 +305,10 @@ exports[`Render should render with base threshold 1`] = `
"grayBlue": "#212327",
"greenBase": "#299c46",
"greenShade": "#23843b",
"headingColor": "#e3e3e3",
"headingColor": "#d8d9da",
"inputBlack": "#09090b",
"link": "#e3e3e3",
"linkDisabled": "#e3e3e3",
"link": "#d8d9da",
"linkDisabled": "#8e8e8e",
"linkExternal": "#33b5e5",
"linkHover": "#ffffff",
"online": "#299c46",
@@ -335,8 +335,8 @@ exports[`Render should render with base threshold 1`] = `
},
"name": "Grafana Dark",
"panelPadding": Object {
"horizontal": 10,
"vertical": 5,
"horizontal": 16,
"vertical": 8,
},
"spacing": Object {
"d": "14px",
@@ -465,7 +465,13 @@ exports[`Render should render with base threshold 1`] = `
type="text"
value="Base"
>
<div>
<div
style={
Object {
"flexGrow": 1,
}
}
>
<input
className="gf-form-input"
readOnly={true}

View File

@@ -197,7 +197,9 @@ $side-menu-width: 60px;
// dashboard
$dashboard-padding: $space-md;
$panel-padding: 0 $space-md $space-sm $space-md;
$panel-padding: 0 ${theme.panelPadding.horizontal}px ${theme.panelPadding.vertical}px ${
theme.panelPadding.horizontal
}px;
// tabs
$tabs-padding: 10px 15px 9px;

View File

@@ -1,4 +1,3 @@
import tinycolor from 'tinycolor2';
import defaultTheme from './default';
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';
@@ -66,11 +65,11 @@ const darkTheme: GrafanaTheme = {
textWeak: basicColors.gray2,
textEmphasis: basicColors.gray5,
textFaint: basicColors.dark5,
link: new tinycolor(basicColors.white).darken(11).toString(),
linkDisabled: new tinycolor(basicColors.white).darken(11).toString(),
link: basicColors.gray4,
linkDisabled: basicColors.gray2,
linkHover: basicColors.white,
linkExternal: basicColors.blue,
headingColor: new tinycolor(basicColors.white).darken(11).toString(),
headingColor: basicColors.gray4,
},
background: {
dropdown: basicColors.dark3,

View File

@@ -67,8 +67,8 @@ const theme: GrafanaThemeCommons = {
},
},
panelPadding: {
horizontal: 10,
vertical: 5,
horizontal: 16,
vertical: 8,
},
zIndex: {
dropdown: '1000',

View File

@@ -1,4 +1,3 @@
import tinycolor from 'tinycolor2';
import defaultTheme from './default';
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';
@@ -65,11 +64,11 @@ const lightTheme: GrafanaTheme = {
text: basicColors.gray1,
textStrong: basicColors.dark2,
textWeak: basicColors.gray2,
textEmphasis: basicColors.gray5,
textEmphasis: basicColors.dark5,
textFaint: basicColors.dark4,
link: basicColors.gray1,
linkDisabled: new tinycolor(basicColors.gray1).lighten(30).toString(),
linkHover: new tinycolor(basicColors.gray1).darken(20).toString(),
linkDisabled: basicColors.gray3,
linkHover: basicColors.dark1,
linkExternal: basicColors.blueLight,
headingColor: basicColors.gray1,
},

View File

@@ -5,7 +5,9 @@ export interface DisplayValue {
title?: string;
}
export type DecimalCount = number | null | undefined;
export interface DecimalInfo {
decimals: number;
scaledDecimals: number;
decimals: DecimalCount;
scaledDecimals: DecimalCount;
}

View File

@@ -158,6 +158,12 @@ describe('Format value', () => {
expect(instance(value).text).toEqual('0.02');
});
it('should use override decimals', () => {
const value = 100030303;
const instance = getDisplayProcessor({ decimals: 2, unit: 'bytes' });
expect(instance(value).text).toEqual('95.40 MiB');
});
it('should return mapped value if there are matching value mappings', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '1-20', type: MappingType.RangeToText, from: '1', to: '20' },
@@ -182,5 +188,6 @@ describe('getDecimalsForValue()', () => {
expect(getDecimalsForValue(20000)).toEqual({ decimals: 0, scaledDecimals: -2 });
expect(getDecimalsForValue(200000)).toEqual({ decimals: 0, scaledDecimals: -3 });
expect(getDecimalsForValue(200000000)).toEqual({ decimals: 0, scaledDecimals: -6 });
expect(getDecimalsForValue(100, 2)).toEqual({ decimals: 2, scaledDecimals: null });
});
});

View File

@@ -8,8 +8,15 @@ import { getMappedValue } from './valueMappings';
import { getColorFromHexRgbOrName } from './namedColorsPalette';
// Types
import { Threshold, ValueMapping, DecimalInfo, DisplayValue, GrafanaTheme, GrafanaThemeType } from '../types';
import { DecimalCount } from './valueFormats/valueFormats';
import {
Threshold,
ValueMapping,
DecimalInfo,
DisplayValue,
GrafanaTheme,
GrafanaThemeType,
DecimalCount,
} from '../types';
export type DisplayProcessor = (value: any) => DisplayValue;
@@ -69,18 +76,7 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce
if (!isNaN(numeric)) {
if (shouldFormat && !_.isBoolean(value)) {
let decimals;
let scaledDecimals = 0;
if (!options.decimals) {
const decimalInfo = getDecimalsForValue(value);
decimals = decimalInfo.decimals;
scaledDecimals = decimalInfo.scaledDecimals;
} else {
decimals = options.decimals;
}
const { decimals, scaledDecimals } = getDecimalsForValue(value, options.decimals);
text = formatFunc(numeric, decimals, scaledDecimals, options.isUtc);
}
if (thresholds && thresholds.length > 0) {
@@ -159,7 +155,12 @@ export function getColorFromThreshold(value: number, thresholds: Threshold[], th
return getColorFromHexRgbOrName(thresholds[0].color, themeType);
}
export function getDecimalsForValue(value: number): DecimalInfo {
export function getDecimalsForValue(value: number, decimalOverride?: DecimalCount): DecimalInfo {
if (_.isNumber(decimalOverride)) {
// It's important that scaledDecimals is null here
return { decimals: decimalOverride, scaledDecimals: null };
}
const delta = value / 2;
let dec = -Math.floor(Math.log(delta) / Math.LN10);

View File

@@ -1,4 +1,5 @@
import { toFixed, DecimalCount } from './valueFormats';
import { toFixed } from './valueFormats';
import { DecimalCount } from '../../types';
export function toPercent(size: number, decimals: DecimalCount) {
if (size === null) {

View File

@@ -1,4 +1,5 @@
import { toFixed, toFixedScaled, DecimalCount } from './valueFormats';
import { toFixed, toFixedScaled } from './valueFormats';
import { DecimalCount } from '../../types';
import moment from 'moment';
interface IntervalsInSeconds {

View File

@@ -1,4 +1,5 @@
import { scaledUnits, DecimalCount } from './valueFormats';
import { scaledUnits } from './valueFormats';
import { DecimalCount } from '../../types';
export function currency(symbol: string) {
const units = ['', 'K', 'M', 'B', 'T'];

View File

@@ -0,0 +1,29 @@
import { toFixed, getValueFormat } from './valueFormats';
describe('kbn.toFixed and negative decimals', () => {
it('should treat as zero decimals', () => {
const str = toFixed(186.123, -2);
expect(str).toBe('186');
});
});
describe('kbn ms format when scaled decimals is null do not use it', () => {
it('should use specified decimals', () => {
const str = getValueFormat('ms')(10000086.123, 1, null);
expect(str).toBe('2.8 hour');
});
});
describe('kbn kbytes format when scaled decimals is null do not use it', () => {
it('should use specified decimals', () => {
const str = getValueFormat('kbytes')(10000000, 3, null);
expect(str).toBe('9.537 GiB');
});
});
describe('kbn deckbytes format when scaled decimals is null do not use it', () => {
it('should use specified decimals', () => {
const str = getValueFormat('deckbytes')(10000000, 3, null);
expect(str).toBe('10.000 GB');
});
});

View File

@@ -1,6 +1,5 @@
import { getCategories } from './categories';
export type DecimalCount = number | null | undefined;
import { DecimalCount } from '../../types';
export type ValueFormatter = (
value: number,

View File

@@ -261,6 +261,10 @@ func UpdateAlertNotification(c *m.ReqContext, cmd m.UpdateAlertNotificationComma
return Error(500, "Failed to update alert notification", err)
}
if cmd.Result == nil {
return Error(404, "Alert notification not found", nil)
}
return JSON(200, dtos.NewAlertNotification(cmd.Result))
}
@@ -272,6 +276,10 @@ func UpdateAlertNotificationByUID(c *m.ReqContext, cmd m.UpdateAlertNotification
return Error(500, "Failed to update alert notification", err)
}
if cmd.Result == nil {
return Error(404, "Alert notification not found", nil)
}
return JSON(200, dtos.NewAlertNotification(cmd.Result))
}

View File

@@ -39,7 +39,7 @@ type AlertNotification struct {
}
type CreateAlertNotificationCommand struct {
Uid string `json:"-"`
Uid string `json:"uid"`
Name string `json:"name" binding:"Required"`
Type string `json:"type" binding:"Required"`
SendReminder bool `json:"sendReminder"`
@@ -54,6 +54,7 @@ type CreateAlertNotificationCommand struct {
type UpdateAlertNotificationCommand struct {
Id int64 `json:"id" binding:"Required"`
Uid string `json:"uid"`
Name string `json:"name" binding:"Required"`
Type string `json:"type" binding:"Required"`
SendReminder bool `json:"sendReminder"`
@@ -68,6 +69,7 @@ type UpdateAlertNotificationCommand struct {
type UpdateAlertNotificationWithUidCommand struct {
Uid string `json:"-"`
NewUid string `json:"uid"`
Name string `json:"name" binding:"Required"`
Type string `json:"type" binding:"Required"`
SendReminder bool `json:"sendReminder"`

View File

@@ -317,6 +317,10 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
current.SendReminder = cmd.SendReminder
current.DisableResolveMessage = cmd.DisableResolveMessage
if cmd.Uid != "" {
current.Uid = cmd.Uid
}
if current.SendReminder {
if cmd.Frequency == "" {
return m.ErrNotificationFrequencyNotFound
@@ -356,8 +360,13 @@ func UpdateAlertNotificationWithUid(cmd *m.UpdateAlertNotificationWithUidCommand
return fmt.Errorf("Cannot update, alert notification uid %s doesn't exist", cmd.Uid)
}
if cmd.NewUid == "" {
cmd.NewUid = cmd.Uid
}
updateNotification := &m.UpdateAlertNotificationCommand{
Id: current.Id,
Uid: cmd.NewUid,
Name: cmd.Name,
Type: cmd.Type,
SendReminder: cmd.SendReminder,
@@ -373,6 +382,8 @@ func UpdateAlertNotificationWithUid(cmd *m.UpdateAlertNotificationWithUidCommand
return err
}
cmd.Result = updateNotification.Result
return nil
}

View File

@@ -18,7 +18,7 @@ var (
)
func init() {
legendFormat = regexp.MustCompile(`\[\[(\w+?)*\]\]*|\$\s*(\w+?)*`)
legendFormat = regexp.MustCompile(`\[\[(\w+)(\.\w+)*\]\]*|\$\s*(\w+?)*`)
}
func (rp *ResponseParser) Parse(response *Response, query *Query) *tsdb.QueryResult {

View File

@@ -75,7 +75,10 @@ func TestInfluxdbResponseParser(t *testing.T) {
{
Name: "cpu.upc",
Columns: []string{"time", "mean", "sum"},
Tags: map[string]string{"datacenter": "America"},
Tags: map[string]string{
"datacenter": "America",
"dc.region.name": "Northeast",
},
Values: [][]interface{}{
{json.Number("111"), json.Number("222"), json.Number("333")},
},
@@ -159,6 +162,13 @@ func TestInfluxdbResponseParser(t *testing.T) {
So(result.Series[0].Name, ShouldEqual, "alias America")
})
Convey("tag alias with periods", func() {
query := &Query{Alias: "alias [[tag_dc.region.name]]"}
result := parser.Parse(response, query)
So(result.Series[0].Name, ShouldEqual, "alias Northeast")
})
})
})
})

View File

@@ -139,7 +139,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
// give angular time to compile
setTimeout(() => {
this.setState({ hasTextEditMode: !!this.angularScope.toggleEditorMode });
}, 10);
}, 100);
}
onToggleCollapse = () => {

View File

@@ -9,6 +9,12 @@ import locationUtil from 'app/core/utils/location_util';
import kbn from 'app/core/utils/kbn';
import { store } from 'app/store/store';
export const queryParamsToPreserve: { [key: string]: boolean } = {
kiosk: true,
autofitpanels: true,
orgId: true,
};
export class PlaylistSrv {
private cancelPromise: any;
private dashboards: Array<{ url: string }>;
@@ -41,9 +47,7 @@ export class PlaylistSrv {
const dash = this.dashboards[this.index];
const queryParams = this.$location.search();
const filteredParams = _.pickBy(queryParams, key => {
return key === 'kiosk' || key === 'autofitpanels' || key === 'orgId';
});
const filteredParams = _.pickBy(queryParams, (value: any, key: string) => queryParamsToPreserve[key]);
const nextDashboardUrl = locationUtil.stripBaseFromUrl(dash.url);
// this is done inside timeout to make sure digest happens after

View File

@@ -8,13 +8,13 @@ export default class DefaultVariableQueryEditor extends PureComponent<VariableQu
this.state = { value: props.query };
}
handleChange(event) {
this.setState({ value: event.target.value });
}
onChange = (event: React.FormEvent<HTMLInputElement>) => {
this.setState({ value: event.currentTarget.value });
};
handleBlur(event) {
this.props.onChange(event.target.value, event.target.value);
}
onBlur = (event: React.FormEvent<HTMLInputElement>) => {
this.props.onChange(event.currentTarget.value, event.currentTarget.value);
};
render() {
return (
@@ -24,8 +24,8 @@ export default class DefaultVariableQueryEditor extends PureComponent<VariableQu
type="text"
className="gf-form-input"
value={this.state.value}
onChange={this.handleChange}
onBlur={this.handleBlur}
onChange={this.onChange}
onBlur={this.onBlur}
placeholder="metric name or tags query"
required
/>

View File

@@ -112,6 +112,7 @@ export class CloudWatchQueryParameterCtrl {
query = $scope.datasource.getDimensionKeys($scope.target.namespace, $scope.target.region);
} else if (segment.type === 'value') {
const dimensionKey = $scope.dimSegments[$index - 2].value;
delete target.dimensions[dimensionKey];
query = $scope.datasource.getDimensionValues(
target.region,
target.namespace,

View File

@@ -966,7 +966,6 @@ export class FuncInstance {
const str = this.def.name + '(';
const parameters = _.map(this.params, (value, index) => {
const valueInterpolated = replaceVariables(value);
let paramType;
if (index < this.def.params.length) {
@@ -980,6 +979,8 @@ export class FuncInstance {
return value;
}
const valueInterpolated = _.isString(value) ? replaceVariables(value) : value;
// param types that might be quoted
// To quote variables correctly we need to interpolate it to check if it contains a numeric or string value
if (_.includes(['int_or_interval', 'node_or_tag'], paramType) && _.isFinite(+valueInterpolated)) {

View File

@@ -19,6 +19,7 @@ export default class GraphiteQuery {
this.datasource = datasource;
this.target = target;
this.templateSrv = templateSrv;
this.scopedVars = scopedVars;
this.parseTarget();
this.removeTagValue = '-- remove tag --';
@@ -162,7 +163,9 @@ export default class GraphiteQuery {
updateModelTarget(targets) {
const wrapFunction = (target: string, func: any) => {
return func.render(target, this.templateSrv.replace);
return func.render(target, (value: string) => {
return this.templateSrv.replace(value, this.scopedVars);
});
};
if (!this.target.textEditor) {

View File

@@ -31,7 +31,8 @@ describe('when creating func instance from func names', () => {
});
function replaceVariablesDummy(str: string) {
return str;
// important that this does replace
return str.replace('asdasdas', 'asdsad');
}
describe('when rendering func instance', () => {

View File

@@ -398,7 +398,13 @@ Array [
>
Alias By
</label>
<div>
<div
style={
Object {
"flexGrow": 1,
}
}
>
<input
className="gf-form-input gf-form-input width-24"
onChange={[Function]}
@@ -426,7 +432,13 @@ Array [
>
Project
</span>
<div>
<div
style={
Object {
"flexGrow": 1,
}
}
>
<input
className="gf-form-input gf-form-input width-15"
disabled={true}

View File

@@ -102,14 +102,14 @@ $edit-gradient: linear-gradient(180deg, $dark-2 50%, $input-black);
// Links
// -------------------------
$link-color: #e3e3e3;
$link-color-disabled: #e3e3e3;
$link-color: #d8d9da;
$link-color-disabled: #8e8e8e;
$link-hover-color: #ffffff;
$external-link-color: #33b5e5;
// Typography
// -------------------------
$headings-color: #e3e3e3;
$headings-color: #d8d9da;
$abbr-border-color: $gray-2 !default;
$text-muted: $text-color-weak;

View File

@@ -200,7 +200,7 @@ $side-menu-width: 60px;
// dashboard
$dashboard-padding: $space-md;
$panel-padding: 0 $space-md $space-sm $space-md;
$panel-padding: 0 16px 8px 16px;
// tabs
$tabs-padding: 10px 15px 9px;

View File

@@ -76,7 +76,7 @@ $text-color: #52545c;
$text-color-strong: #41444b;
$text-color-weak: #767980;
$text-color-faint: #35373f;
$text-color-emphasis: #dde4ed;
$text-color-emphasis: #41444b;
$text-shadow-faint: none;
@@ -89,8 +89,8 @@ $edit-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%);
// Links
// -------------------------
$link-color: #52545c;
$link-color-disabled: #9ea0a9;
$link-hover-color: #222326;
$link-color-disabled: #acb6bf;
$link-hover-color: #1e2028;
$external-link-color: #5794f2;
// Typography

View File

@@ -153,7 +153,7 @@
.share-modal-info-text {
margin-top: 5px;
strong {
color: $headings-color;
color: $text-color-emphasis;
font-weight: 500;
}
}

View File

@@ -335,7 +335,6 @@
}
@mixin left-brand-border-gradient() {
border: none;
border-image: linear-gradient(rgba(255, 213, 0, 1) 0%, rgba(255, 68, 0, 1) 99%, rgba(255, 68, 0, 1) 100%);
border-image-slice: 1;
border-style: solid;

View File

@@ -18,7 +18,9 @@ RUN pip install -U awscli crcmod && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/* && \
ln -s /opt/google-cloud-sdk/bin/gsutil /usr/bin/gsutil && \
ln -s /opt/google-cloud-sdk/bin/gcloud /usr/bin/gcloud
ln -s /opt/google-cloud-sdk/bin/gcloud /usr/bin/gcloud && \
mkdir -p /deb-repo /rpm-repo && \
chown circleci:circleci /deb-repo /rpm-repo
COPY --from=0 /go/bin/aptly /usr/local/bin/aptly

View File

@@ -1,6 +1,6 @@
#!/bin/bash
_version="1.2.1"
_version="1.2.2"
_tag="grafana/grafana-ci-deploy:${_version}"
docker build -t $_tag .

View File

@@ -6,8 +6,8 @@ EXTRA_OPTS="$@"
# Right now we hack this in into the publish script.
# Eventually we might want to keep a list of all previous releases somewhere.
_releaseNoteUrl="https://community.grafana.com/t/release-notes-v6-0-x/14010"
_whatsNewUrl="http://docs.grafana.org/guides/whats-new-in-v6-0/"
_releaseNoteUrl="https://community.grafana.com/t/release-notes-v6-1-x/15772"
_whatsNewUrl="http://docs.grafana.org/guides/whats-new-in-v6-1/"
./scripts/build/release_publisher/release_publisher \
--wn ${_whatsNewUrl} \

View File

@@ -14,21 +14,21 @@ const changelogTaskRunner: TaskRunner<ChangelogOptions> = async ({ milestone })
timeout: 10000,
});
if (!/^\d+$/.test(milestone)) {
console.log('Use milestone number not title, find number in milestone url');
return;
}
const res = await client.get('/issues', {
params: {
state: 'closed',
per_page: 100,
labels: 'add to changelog',
milestone: milestone,
},
});
const issues = res.data.filter(item => {
if (!item.milestone) {
console.log('Item missing milestone', item.number);
return false;
}
return item.milestone.title === milestone;
});
const issues = res.data;
const bugs = _.sortBy(
issues.filter(item => {

View File

@@ -27,13 +27,10 @@ const cherryPickRunner: TaskRunner<CherryPickOptions> = async () => {
continue;
}
console.log(item.number + ' closed_at ' + item.closed_at + ' ' + item.html_url);
console.log(`${item.title} (${item.number}) closed_at ${item.closed_at}`);
console.log(`\tURL: ${item.closed_at} ${item.html_url}`);
const issueDetails = await client.get(item.pull_request.url);
const commits = await client.get(issueDetails.data.commits_url);
for (const commit of commits.data) {
console.log(commit.commit.message + ' sha: ' + commit.sha);
}
console.log(`\tMerge sha: ${issueDetails.data.merge_commit_sha}`);
}
};

View File

@@ -1,7 +1,9 @@
module.exports = {
plugins: {
'autoprefixer': {},
'postcss-reporter': {},
'postcss-browser-reporter': {},
}
}
module.exports = () => {
return {
plugins: {
autoprefixer: {},
'postcss-reporter': {},
'postcss-browser-reporter': {},
}
};
};

View File

@@ -19,7 +19,7 @@ module.exports = function(options) {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap,
config: { path: __dirname + '/postcss.config.js' },
config: { path: __dirname },
},
},
{