diff --git a/docs/sources/alerting/notifications.md b/docs/sources/alerting/notifications.md index 5327039341f..8aafdb0362c 100644 --- a/docs/sources/alerting/notifications.md +++ b/docs/sources/alerting/notifications.md @@ -83,7 +83,11 @@ or a bot integration via Slack Apps. Follow Slack's guide to set up a bot integr Setting | Description ---------- | ----------- -Recipient | allows you to override the Slack recipient. +Url | Slack incoming webhook url. +Username | Set the username for the bot's message. +Recipient | Allows you to override the Slack recipient. +Icon emoji | Provide an emoji to use as the icon for the bot's message. Ex :smile: +Icon URL | Provide a url to an image to use as the icon for the bot's message. Mention | make it possible to include a mention in the Slack notification sent by Grafana. Ex @here or @channel Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination. diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx index f4901b28bfd..3e5639172be 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx @@ -8,7 +8,7 @@ import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; import { UseState } from '../../utils/storybook/UseState'; const BasicGreen = getColorDefinitionByName('green'); -const BasicBlue = getColorDefinitionByName('blue'); +const BasicRed = getColorDefinitionByName('red'); const LightBlue = getColorDefinitionByName('light-blue'); const NamedColorsPaletteStories = storiesOf('UI/ColorPicker/Palettes/NamedColorsPalette', module); @@ -41,7 +41,7 @@ NamedColorsPaletteStories.add('Named colors swatch - support for named colors', 'Selected color', { Green: BasicGreen.variants.dark, - Red: BasicBlue.variants.dark, + Red: BasicRed.variants.dark, 'Light blue': LightBlue.variants.dark, }, 'red' diff --git a/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts index b8919c682e2..fb4e454d2f9 100644 --- a/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts +++ b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts @@ -1,9 +1,9 @@ -import propDeprecationWarning from '../../utils/propDeprecationWarning'; +import deprecationWarning from '../../utils/deprecationWarning'; import { ColorPickerProps } from './ColorPickerPopover'; export const warnAboutColorPickerPropsDeprecation = (componentName: string, props: ColorPickerProps) => { const { onColorChange } = props; if (onColorChange) { - propDeprecationWarning(componentName, 'onColorChange', 'onChange'); + deprecationWarning(componentName, 'onColorChange', 'onChange'); } }; diff --git a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.story.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.story.tsx index ccbccea9c5c..0f5e85414eb 100644 --- a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.story.tsx +++ b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.story.tsx @@ -1,24 +1,17 @@ -import React, { FunctionComponent } from 'react'; +import React from 'react'; import { storiesOf } from '@storybook/react'; import { DeleteButton } from './DeleteButton'; - -const CenteredStory: FunctionComponent<{}> = ({ children }) => { - return ( -
- {children} -
- ); -}; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { action } from '@storybook/addon-actions'; storiesOf('UI/DeleteButton', module) - .addDecorator(story => {story()}) + .addDecorator(withCenteredStory) .add('default', () => { - return {}} />; + return ( + { + action('Delete Confirmed')('delete!'); + }} + /> + ); }); diff --git a/packages/grafana-ui/src/utils/deprecationWarning.ts b/packages/grafana-ui/src/utils/deprecationWarning.ts new file mode 100644 index 00000000000..3182f232638 --- /dev/null +++ b/packages/grafana-ui/src/utils/deprecationWarning.ts @@ -0,0 +1,6 @@ +const deprecationWarning = (file: string, oldName: string, newName: string) => { + const message = `[Deprecation warning] ${file}: ${oldName} is deprecated. Use ${newName} instead`; + console.warn(message); +}; + +export default deprecationWarning; diff --git a/packages/grafana-ui/src/utils/index.ts b/packages/grafana-ui/src/utils/index.ts index c5f4b2c5b1b..a2acc828752 100644 --- a/packages/grafana-ui/src/utils/index.ts +++ b/packages/grafana-ui/src/utils/index.ts @@ -2,4 +2,6 @@ export * from './processTimeSeries'; export * from './valueFormats/valueFormats'; export * from './colors'; export * from './namedColorsPalette'; +export * from './string'; +export * from './deprecationWarning'; export { getMappedValue } from './valueMappings'; diff --git a/packages/grafana-ui/src/utils/propDeprecationWarning.ts b/packages/grafana-ui/src/utils/propDeprecationWarning.ts deleted file mode 100644 index a277395c090..00000000000 --- a/packages/grafana-ui/src/utils/propDeprecationWarning.ts +++ /dev/null @@ -1,6 +0,0 @@ -const propDeprecationWarning = (componentName: string, propName: string, newPropName: string) => { - const message = `[Deprecation warning] ${componentName}: ${propName} is deprecated. Use ${newPropName} instead`; - console.warn(message); -}; - -export default propDeprecationWarning; diff --git a/packages/grafana-ui/src/utils/string.test.ts b/packages/grafana-ui/src/utils/string.test.ts new file mode 100644 index 00000000000..a6b35461d78 --- /dev/null +++ b/packages/grafana-ui/src/utils/string.test.ts @@ -0,0 +1,15 @@ +import { stringToJsRegex } from '@grafana/ui'; + +describe('stringToJsRegex', () => { + it('should parse the valid regex value', () => { + const output = stringToJsRegex('/validRegexp/'); + expect(output).toBeInstanceOf(RegExp); + }); + + it('should throw error on invalid regex value', () => { + const input = '/etc/hostname'; + expect(() => { + stringToJsRegex(input); + }).toThrow(); + }); +}); diff --git a/packages/grafana-ui/src/utils/string.ts b/packages/grafana-ui/src/utils/string.ts new file mode 100644 index 00000000000..12433623a6a --- /dev/null +++ b/packages/grafana-ui/src/utils/string.ts @@ -0,0 +1,13 @@ +export function stringToJsRegex(str: string): RegExp { + if (str[0] !== '/') { + return new RegExp('^' + str + '$'); + } + + const match = str.match(new RegExp('^/(.*?)/(g?i?m?y?)$')); + + if (!match) { + throw new Error(`'${str}' is not a valid regular expression.`); + } + + return new RegExp(match[1], match[2]); +} diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts index 23a0a0c19ea..10c91c148d7 100644 --- a/public/app/core/time_series2.ts +++ b/public/app/core/time_series2.ts @@ -1,7 +1,6 @@ -import kbn from 'app/core/utils/kbn'; import { getFlotTickDecimals } from 'app/core/utils/ticks'; import _ from 'lodash'; -import { getValueFormat } from '@grafana/ui'; +import { getValueFormat, stringToJsRegex } from '@grafana/ui'; function matchSeriesOverride(aliasOrRegex, seriesAlias) { if (!aliasOrRegex) { @@ -9,7 +8,7 @@ function matchSeriesOverride(aliasOrRegex, seriesAlias) { } if (aliasOrRegex[0] === '/') { - const regex = kbn.stringToJsRegex(aliasOrRegex); + const regex = stringToJsRegex(aliasOrRegex); return seriesAlias.match(regex) != null; } diff --git a/public/app/core/utils/kbn.ts b/public/app/core/utils/kbn.ts index 43886fafd07..d747fa37f57 100644 --- a/public/app/core/utils/kbn.ts +++ b/public/app/core/utils/kbn.ts @@ -1,5 +1,6 @@ import _ from 'lodash'; -import { getValueFormat, getValueFormatterIndex, getValueFormats } from '@grafana/ui'; +import { getValueFormat, getValueFormatterIndex, getValueFormats, stringToJsRegex } from '@grafana/ui'; +import deprecationWarning from '@grafana/ui/src/utils/deprecationWarning'; const kbn: any = {}; @@ -228,18 +229,10 @@ kbn.slugifyForUrl = str => { .replace(/ +/g, '-'); }; +/** deprecated since 6.1, use grafana/ui */ kbn.stringToJsRegex = str => { - if (str[0] !== '/') { - return new RegExp('^' + str + '$'); - } - - const match = str.match(new RegExp('^/(.*?)/(g?i?m?y?)$')); - - if (!match) { - throw new Error(`'${str}' is not a valid regular expression.`); - } - - return new RegExp(match[1], match[2]); + deprecationWarning('kbn.ts', 'kbn.stringToJsRegex()', '@grafana/ui'); + return stringToJsRegex(str); }; kbn.toFixed = (value, decimals) => { diff --git a/public/app/features/templating/datasource_variable.ts b/public/app/features/templating/datasource_variable.ts index 4424720c7f8..2b326cb1c5c 100644 --- a/public/app/features/templating/datasource_variable.ts +++ b/public/app/features/templating/datasource_variable.ts @@ -1,5 +1,5 @@ -import kbn from 'app/core/utils/kbn'; import { Variable, containsVariable, assignModelProperties, variableTypes } from './variable'; +import { stringToJsRegex } from '@grafana/ui'; export class DatasourceVariable implements Variable { regex: any; @@ -47,7 +47,7 @@ export class DatasourceVariable implements Variable { if (this.regex) { regex = this.templateSrv.replace(this.regex, null, 'regex'); - regex = kbn.stringToJsRegex(regex); + regex = stringToJsRegex(regex); } for (let i = 0; i < sources.length; i++) { diff --git a/public/app/features/templating/query_variable.ts b/public/app/features/templating/query_variable.ts index 0aec1d8f412..8208345528b 100644 --- a/public/app/features/templating/query_variable.ts +++ b/public/app/features/templating/query_variable.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; -import kbn from 'app/core/utils/kbn'; import { Variable, containsVariable, assignModelProperties, variableTypes } from './variable'; +import { stringToJsRegex } from '@grafana/ui'; function getNoneOption() { return { text: 'None', value: '', isNone: true }; @@ -148,7 +148,7 @@ export class QueryVariable implements Variable { options = []; if (this.regex) { - regex = kbn.stringToJsRegex(this.templateSrv.replace(this.regex, {}, 'regex')); + regex = stringToJsRegex(this.templateSrv.replace(this.regex, {}, 'regex')); } for (i = 0; i < metricNames.length; i++) { const item = metricNames[i]; diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index e9bf89f45fe..6b6189f7482 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -1,7 +1,6 @@ import _ from 'lodash'; import moment from 'moment'; -import kbn from 'app/core/utils/kbn'; -import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType } from '@grafana/ui'; +import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType, stringToJsRegex } from '@grafana/ui'; export class TableRenderer { formatters: any[]; @@ -35,7 +34,7 @@ export class TableRenderer { for (let i = 0; i < this.panel.styles.length; i++) { const style = this.panel.styles[i]; - const regex = kbn.stringToJsRegex(style.pattern); + const regex = stringToJsRegex(style.pattern); if (column.text.match(regex)) { column.style = style;