mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Part3: Unicons implementation (#23356)
* Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Implment icons in Tabs * Implement icons in search items and empty list * Update buttons * Update button-related snapshot tests * Update icons in modals and page headers * Create anfular wrapper and update all icons on search screen * Update sizing, remove colors, update snapshot tests * Remove color prop from icon, remove color implemetation in mono icons * Remove color props from monochrome icons * Complete update of icons for search screen * Update icons for infor tooltips, playlist, permissions * Support temporarly font awesome icons used in enterprise grafana * Part1: Unicons implementation (#23197) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179) * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Remove color prop from icon, remove color implemetation in mono icons * Update navbar styling * Move toPascalCase to utils/string Co-authored-by: Torkel Ödegaard <torkel@grafana.com> * Update icons in Explore * Update icons in alerting * Update + and x buttons * Update icons in configurations and settings * Update close icons * Update icons in rich history * Update alert messages * Add optional chaining to for isFontAwesome variable * Remove icon mock, set up jest.config * Fix navbar plus icon * Fir enable-bacground to enableBackgournd Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
parent
d2d61d9bc2
commit
bc468e4b92
@ -1,8 +1,12 @@
|
||||
const esModule = '@iconscout/react-unicons';
|
||||
|
||||
module.exports = {
|
||||
verbose: false,
|
||||
transform: {
|
||||
'^.+\\.(ts|tsx|js|jsx)$': 'ts-jest',
|
||||
[`(${esModule}).+\\.js$`]: 'babel-jest',
|
||||
},
|
||||
transformIgnorePatterns: [`/node_modules/(?!${esModule})`],
|
||||
moduleDirectories: ['node_modules', 'public'],
|
||||
roots: ['<rootDir>/public/app', '<rootDir>/public/test', '<rootDir>/packages', '<rootDir>/scripts'],
|
||||
testRegex: '(\\.|/)(test)\\.(jsx?|tsx?)$',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { FC, ReactNode } from 'react';
|
||||
import { Icon, IconName } from '@grafana/ui';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export type AlertVariant = 'success' | 'warning' | 'error' | 'info';
|
||||
@ -15,16 +16,16 @@ interface AlertProps {
|
||||
function getIconFromSeverity(severity: AlertVariant): string {
|
||||
switch (severity) {
|
||||
case 'error': {
|
||||
return 'fa fa-exclamation-triangle';
|
||||
return 'exclamation-triangle';
|
||||
}
|
||||
case 'warning': {
|
||||
return 'fa fa-exclamation-triangle';
|
||||
return 'exclamation-triangle';
|
||||
}
|
||||
case 'info': {
|
||||
return 'fa fa-info-circle';
|
||||
return 'info-circle';
|
||||
}
|
||||
case 'success': {
|
||||
return 'fa fa-check';
|
||||
return 'check';
|
||||
}
|
||||
default:
|
||||
return '';
|
||||
@ -37,7 +38,7 @@ export const Alert: FC<AlertProps> = ({ title, buttonText, onButtonClick, onRemo
|
||||
<div className="alert-container">
|
||||
<div className={alertClass}>
|
||||
<div className="alert-icon">
|
||||
<i className={getIconFromSeverity(severity)} />
|
||||
<Icon size="xl" name={getIconFromSeverity(severity) as IconName} />
|
||||
</div>
|
||||
<div className="alert-body">
|
||||
<div className="alert-title">{title}</div>
|
||||
@ -46,7 +47,7 @@ export const Alert: FC<AlertProps> = ({ title, buttonText, onButtonClick, onRemo
|
||||
{/* If onRemove is specified , giving preference to onRemove */}
|
||||
{onRemove && (
|
||||
<button type="button" className="alert-close" onClick={onRemove}>
|
||||
<i className="fa fa fa-remove" />
|
||||
<Icon name="times" size="lg" />
|
||||
</button>
|
||||
)}
|
||||
{onButtonClick && (
|
||||
|
@ -12,7 +12,7 @@ CallToActionCardStories.add('default', () => {
|
||||
const ctaElements: { [key: string]: JSX.Element } = {
|
||||
custom: <h1>This is just H1 tag, you can any component as CTA element</h1>,
|
||||
button: (
|
||||
<Button size="lg" icon="plus" onClick={action('cta button clicked')}>
|
||||
<Button size="lg" icon="plus-circle" onClick={action('cta button clicked')}>
|
||||
Add datasource
|
||||
</Button>
|
||||
),
|
||||
|
@ -73,7 +73,7 @@ export const DataLinksEditor: FC<DataLinksEditorProps> = React.memo(
|
||||
)}
|
||||
|
||||
{(!value || (value && value.length < (maxLinks || Infinity))) && (
|
||||
<Button variant="secondary" icon="plus" onClick={() => onAdd()}>
|
||||
<Button variant="secondary" icon="plus-circle" onClick={() => onAdd()}>
|
||||
Add link
|
||||
</Button>
|
||||
)}
|
||||
|
@ -100,7 +100,7 @@ export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ li
|
||||
)}
|
||||
|
||||
<FullWidthButtonContainer>
|
||||
<Button size="sm" icon="plus" onClick={onDataLinkAdd} variant="secondary">
|
||||
<Button size="sm" icon="plus-circle" onClick={onDataLinkAdd} variant="secondary">
|
||||
Add link
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { KeyValue } from '@grafana/data';
|
||||
import { css, cx } from 'emotion';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { CertificationKey } from './CertificationKey';
|
||||
import { HttpSettingsBaseProps } from './types';
|
||||
|
||||
@ -47,7 +48,7 @@ export const TLSAuthSettings: React.FC<HttpSettingsBaseProps> = ({ dataSourceCon
|
||||
theme="info"
|
||||
>
|
||||
<div className="gf-form-help-icon gf-form-help-icon--right-normal">
|
||||
<i className="fa fa-info-circle" />
|
||||
<Icon name="info-circle" size="sm" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@ export const FormLabel: FunctionComponent<Props> = ({
|
||||
{tooltip && (
|
||||
<Tooltip placement="top" content={tooltip} theme={'info'}>
|
||||
<div className="gf-form-help-icon gf-form-help-icon--right-normal">
|
||||
<Icon name="info-circle" />
|
||||
<Icon name="info-circle" size="sm" style={{ marginBottom: 0 }} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
@ -136,7 +136,6 @@ $select-input-bg-disabled: $input-bg-disabled;
|
||||
height: 100%;
|
||||
right: 8px;
|
||||
top: 1px;
|
||||
margin-top: -1px;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ const getIconStyles = stylesFactory((theme: GrafanaTheme, type: IconType) => {
|
||||
});
|
||||
|
||||
export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
|
||||
({ size = 'md', type = 'default', title, name, className, style, ...divElementProps }, ref) => {
|
||||
({ size = 'md', type = 'default', name, className, style, ...divElementProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const styles = getIconStyles(theme, type);
|
||||
const svgSize = getSvgSize(size, theme);
|
||||
|
@ -5,7 +5,7 @@ export const Bell: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
enableBackground="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
|
@ -5,7 +5,7 @@ export const FolderPlus: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
enableBackground="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
|
@ -5,7 +5,7 @@ export const Import: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
enableBackground="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
|
@ -5,7 +5,7 @@ export const PlusSquare: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
enableBackground="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
|
@ -37,7 +37,7 @@ describe('LogDetails', () => {
|
||||
describe('when labels are present', () => {
|
||||
it('should render heading', () => {
|
||||
const wrapper = setup(undefined, { labels: { key1: 'label1', key2: 'label2' } });
|
||||
expect(wrapper.find({ 'aria-label': 'Log Labels' })).toHaveLength(1);
|
||||
expect(wrapper.find({ 'aria-label': 'Log Labels' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
it('should render labels', () => {
|
||||
const wrapper = setup(undefined, { labels: { key1: 'label1', key2: 'label2' } });
|
||||
@ -47,7 +47,7 @@ describe('LogDetails', () => {
|
||||
describe('when row entry has parsable fields', () => {
|
||||
it('should render heading ', () => {
|
||||
const wrapper = setup(undefined, { entry: 'test=successful' });
|
||||
expect(wrapper.find({ title: 'Ad-hoc statistics' })).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Ad-hoc statistics' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
it('should render parsed fields', () => {
|
||||
const wrapper = setup(undefined, { entry: 'test=successful' });
|
||||
@ -116,7 +116,7 @@ describe('LogDetails', () => {
|
||||
expect(wrapper.find(LogDetailsRow).length).toBe(3);
|
||||
const traceIdRow = wrapper.find(LogDetailsRow).filter({ parsedKey: 'traceId' });
|
||||
expect(traceIdRow.length).toBe(1);
|
||||
expect(traceIdRow.find('a').length).toBe(1);
|
||||
expect(traceIdRow.find('a').hostNodes().length).toBe(1);
|
||||
expect((traceIdRow.find('a').getDOMNode() as HTMLAnchorElement).href).toBe('localhost:3210/1234');
|
||||
});
|
||||
});
|
||||
|
@ -32,16 +32,16 @@ describe('LogDetailsRow', () => {
|
||||
});
|
||||
it('should render metrics button', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find('i.fa-signal')).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Ad-hoc statistics' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
describe('if props is a label', () => {
|
||||
it('should render filter label button', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find('i.fa-search-plus')).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Filter for value' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
it('should render filter out label button', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find('i.fa-search-minus')).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Filter out value' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -66,7 +66,10 @@ describe('LogDetailsRow', () => {
|
||||
});
|
||||
|
||||
expect(wrapper.find(LogLabelStats).length).toBe(0);
|
||||
wrapper.find({ title: 'Ad-hoc statistics' }).simulate('click');
|
||||
wrapper
|
||||
.find({ title: 'Ad-hoc statistics' })
|
||||
.hostNodes()
|
||||
.simulate('click');
|
||||
expect(wrapper.find(LogLabelStats).length).toBe(1);
|
||||
expect(wrapper.find(LogLabelStats).contains('another value')).toBeTruthy();
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ import { stylesFactory } from '../../themes/stylesFactory';
|
||||
//Components
|
||||
import { LogLabelStats } from './LogLabelStats';
|
||||
import { LinkButton } from '../Button/Button';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
export interface Props extends Themeable {
|
||||
parsedValue: string;
|
||||
@ -94,24 +95,16 @@ class UnThemedLogDetailsRow extends PureComponent<Props, State> {
|
||||
<tr className={cx(style.logDetailsValue, { [styles.noHoverBackground]: showFieldsStats })}>
|
||||
{/* Action buttons - show stats/filter results */}
|
||||
<td className={style.logsDetailsIcon} colSpan={isLabel ? undefined : 3}>
|
||||
<i title="Ad-hoc statistics" className={`fa fa-signal ${styles.hoverCursor}`} onClick={this.showStats} />
|
||||
<Icon name="signal" title={'Ad-hoc statistics'} onClick={this.showStats} />
|
||||
</td>
|
||||
|
||||
{isLabel && (
|
||||
<>
|
||||
<td className={style.logsDetailsIcon}>
|
||||
<i
|
||||
title="Filter for value"
|
||||
className={`fa fa-search-plus ${styles.hoverCursor}`}
|
||||
onClick={this.filterLabel}
|
||||
/>
|
||||
<Icon name="search-minus" title="Filter for value" onClick={this.filterLabel} />
|
||||
</td>
|
||||
<td className={style.logsDetailsIcon}>
|
||||
<i
|
||||
title="Filter out value"
|
||||
className={`fa fa-search-minus ${styles.hoverCursor}`}
|
||||
onClick={this.filterOutLabel}
|
||||
/>
|
||||
<Icon name="search-plus" title="Filter out value" onClick={this.filterOutLabel} />
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Field, LinkModel, LogRowModel, TimeZone, DataQueryResponse, GrafanaTheme } from '@grafana/data';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import { cx, css } from 'emotion';
|
||||
|
||||
import {
|
||||
@ -48,6 +49,8 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
topVerticalAlign: css`
|
||||
label: topVerticalAlign;
|
||||
vertical-align: top;
|
||||
margin-top: -${theme.spacing.xs};
|
||||
margin-left: -${theme.spacing.xxs};
|
||||
`,
|
||||
hoverBackground: css`
|
||||
label: hoverBackground;
|
||||
@ -129,9 +132,6 @@ class UnThemedLogRow extends PureComponent<Props, State> {
|
||||
const style = getLogRowStyles(theme, row.logLevel);
|
||||
const styles = getStyles(theme);
|
||||
const showUtc = timeZone === 'utc';
|
||||
const showDetailsClassName = showDetails
|
||||
? cx(['fa fa-chevron-down', styles.topVerticalAlign])
|
||||
: cx(['fa fa-chevron-right', styles.topVerticalAlign]);
|
||||
const hoverBackground = cx(style.logsRow, { [styles.hoverBackground]: hasHoverBackground });
|
||||
|
||||
return (
|
||||
@ -150,7 +150,7 @@ class UnThemedLogRow extends PureComponent<Props, State> {
|
||||
<td className={style.logsRowLevel} />
|
||||
{!allowDetails && (
|
||||
<td title={showDetails ? 'Hide log details' : 'See log details'} className={style.logsRowToggleDetails}>
|
||||
<i className={showDetailsClassName} />
|
||||
<Icon className={styles.topVerticalAlign} name={showDetails ? 'angle-down' : 'angle-right'} />
|
||||
</td>
|
||||
)}
|
||||
{showTime && showUtc && (
|
||||
|
@ -158,8 +158,10 @@ export const getLogRowStyles = stylesFactory((theme: GrafanaTheme, logLevel?: Lo
|
||||
logsDetailsIcon: css`
|
||||
label: logs-row-details__icon;
|
||||
position: relative;
|
||||
padding-right: ${theme.spacing.md};
|
||||
color: ${theme.colors.gray3};
|
||||
svg {
|
||||
margin-right: ${theme.spacing.md};
|
||||
}
|
||||
`,
|
||||
logDetailsLabel: css`
|
||||
label: logs-row-details__label;
|
||||
|
@ -6,6 +6,7 @@ import { IconName } from '../../types';
|
||||
import { Themeable } from '../../types';
|
||||
import { getModalStyles } from './getModalStyles';
|
||||
import { ModalHeader } from './ModalHeader';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
interface Props extends Themeable {
|
||||
icon?: IconName;
|
||||
@ -50,7 +51,7 @@ export class UnthemedModal extends React.PureComponent<Props> {
|
||||
<div className={styles.modalHeader}>
|
||||
{typeof title === 'string' ? this.renderDefaultHeader(title) : title}
|
||||
<a className={styles.modalHeaderClose} onClick={this.onDismiss}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
</div>
|
||||
<div className={styles.modalContent}>{this.props.children}</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Libraries
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
title?: string | JSX.Element;
|
||||
@ -26,7 +27,7 @@ export const PanelOptionsGroup: FunctionComponent<Props> = props => {
|
||||
<span className="panel-options-group__title">{props.title}</span>
|
||||
{props.onClose && (
|
||||
<button className="btn btn-link" onClick={props.onClose}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -200,7 +200,7 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<FullWidthButtonContainer className={styles.addButton}>
|
||||
<Button size="sm" icon="plus" onClick={() => this.onAddThreshold()} variant="secondary">
|
||||
<Button size="sm" icon="plus-circle" onClick={() => this.onAddThreshold()} variant="secondary">
|
||||
Add threshold
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
@ -118,7 +118,7 @@ export class TransformationsEditor extends React.PureComponent<TransformationsEd
|
||||
return (
|
||||
<>
|
||||
{this.renderTransformationEditors()}
|
||||
<Button variant="secondary" icon="plus" onClick={this.onTransformationAdd}>
|
||||
<Button variant="secondary" icon="plus-circle" onClick={this.onTransformationAdd}>
|
||||
Add transformation
|
||||
</Button>
|
||||
</>
|
||||
|
@ -98,7 +98,7 @@ export class LegacyValueMappingsEditor extends PureComponent<Props, State> {
|
||||
removeValueMapping={() => this.onRemoveMapping(valueMapping.id)}
|
||||
/>
|
||||
))}
|
||||
<Button variant="primary" icon="plus" onClick={this.onAddMapping}>
|
||||
<Button variant="primary" icon="plus-circle" onClick={this.onAddMapping}>
|
||||
Add mapping
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -68,7 +68,7 @@ export const ValueMappingsEditor: React.FC<Props> = ({ valueMappings, onChange,
|
||||
<FullWidthButtonContainer>
|
||||
<Button
|
||||
size="sm"
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
onClick={onAdd}
|
||||
aria-label="ValueMappingsEditor add mapping button"
|
||||
variant="secondary"
|
||||
|
@ -35,7 +35,7 @@ exports[`Render should render component 1`] = `
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
onClick={[Function]}
|
||||
variant="primary"
|
||||
>
|
||||
|
@ -23,7 +23,7 @@ export function ValuePicker<T>({ label, icon, options, onChange, variant }: Valu
|
||||
<>
|
||||
{!isPicking && (
|
||||
<FullWidthButtonContainer>
|
||||
<Button size="sm" icon={icon || 'plus'} onClick={() => setIsPicking(true)} variant={variant}>
|
||||
<Button size="sm" icon={icon || 'plus-circle'} onClick={() => setIsPicking(true)} variant={variant}>
|
||||
{label}
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
@ -3,10 +3,12 @@ export type IconType = 'mono' | 'default';
|
||||
export type IconName =
|
||||
| 'fa fa-fw fa-unlock'
|
||||
| 'fa fa-envelope'
|
||||
| 'fa fa-spinner'
|
||||
| 'question-circle'
|
||||
| 'plus'
|
||||
| 'angle-up'
|
||||
| 'history'
|
||||
| 'angle-down'
|
||||
| 'filter'
|
||||
| 'angle-left'
|
||||
| 'angle-right'
|
||||
| 'pen'
|
||||
@ -34,6 +36,8 @@ export type IconName =
|
||||
| 'panel-add'
|
||||
| 'arrow-random'
|
||||
| 'arrow-down'
|
||||
| 'comment-alt'
|
||||
| 'arrow-right'
|
||||
| 'arrow-up'
|
||||
| 'arrow-from-right'
|
||||
| 'keyboard'
|
||||
@ -50,9 +54,12 @@ export type IconName =
|
||||
| 'folder-plus'
|
||||
| 'link'
|
||||
| 'upload'
|
||||
| 'columns'
|
||||
| 'home-alt'
|
||||
| 'channel-add'
|
||||
| 'calendar-alt'
|
||||
| 'play'
|
||||
| 'pause'
|
||||
| 'calculator-alt'
|
||||
| 'compass'
|
||||
| 'sliders-v-alt'
|
||||
@ -77,12 +84,20 @@ export type IconName =
|
||||
| 'edit'
|
||||
| 'shield'
|
||||
| 'eye'
|
||||
| 'eye-slash'
|
||||
| 'filter'
|
||||
| 'monitor'
|
||||
| 'plus-circle'
|
||||
| 'arrow-left'
|
||||
| 'repeat'
|
||||
| 'external-link-alt'
|
||||
| 'minus'
|
||||
| 'signal'
|
||||
| 'search-plus'
|
||||
| 'search-minus'
|
||||
| 'table'
|
||||
| 'plus'
|
||||
| 'heart'
|
||||
| 'favorite';
|
||||
|
||||
export const getAvailableIcons = (): IconName[] => [
|
||||
@ -102,6 +117,8 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'repeat',
|
||||
'external-link-alt',
|
||||
'power',
|
||||
'play',
|
||||
'pause',
|
||||
'trash-alt',
|
||||
'exclamation-triangle',
|
||||
'times',
|
||||
@ -152,8 +169,10 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'info-circle',
|
||||
'bug',
|
||||
'cube',
|
||||
'history',
|
||||
'star',
|
||||
'edit',
|
||||
'columns',
|
||||
'eye',
|
||||
'channel-add',
|
||||
'monitor',
|
||||
@ -164,6 +183,7 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'folder-open',
|
||||
'file-copy-alt',
|
||||
'arrow-down',
|
||||
'filter',
|
||||
'arrow-up',
|
||||
'exchange-alt',
|
||||
];
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export type LayoutMode = LayoutModes.Grid | LayoutModes.List;
|
||||
|
||||
@ -22,7 +23,7 @@ const LayoutSelector: FC<Props> = props => {
|
||||
}}
|
||||
className={mode === LayoutModes.List ? 'active' : ''}
|
||||
>
|
||||
<i className="fa fa-list" />
|
||||
<Icon name="list-ul" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
@ -30,7 +31,7 @@ const LayoutSelector: FC<Props> = props => {
|
||||
}}
|
||||
className={mode === LayoutModes.Grid ? 'active' : ''}
|
||||
>
|
||||
<i className="fa fa-th" />
|
||||
<Icon name="table" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { UserPicker } from 'app/core/components/Select/UserPicker';
|
||||
import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import { LegacyForms, Icon } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { User } from 'app/types';
|
||||
import {
|
||||
@ -91,7 +91,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
|
||||
return (
|
||||
<div className="gf-form-inline cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={onCancel}>
|
||||
<i className="fa fa-close" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
<form name="addPermission" onSubmit={this.onSubmit}>
|
||||
<h5>Add Permission For</h5>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { getTagColorsFromName } from '@grafana/ui';
|
||||
import { getTagColorsFromName, Icon } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
label: string;
|
||||
@ -24,7 +24,7 @@ export class TagBadge extends React.Component<Props, any> {
|
||||
|
||||
return (
|
||||
<span className={`label label-tag`} style={tagStyle}>
|
||||
{removeIcon && <i className="fa fa-remove" />}
|
||||
{removeIcon && <Icon name="times" />}
|
||||
{label} {countLabel}
|
||||
</span>
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { appEvents } from 'app/core/core';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export class HelpModal extends React.PureComponent {
|
||||
static tabIndex = 0;
|
||||
@ -52,11 +53,11 @@ export class HelpModal extends React.PureComponent {
|
||||
<div className="modal-body">
|
||||
<div className="modal-header">
|
||||
<h2 className="modal-header-title">
|
||||
<i className="fa fa-keyboard-o" />
|
||||
<Icon name="keyboard" size="lg" />
|
||||
<span className="p-l-1">Shortcuts</span>
|
||||
</h2>
|
||||
<a className="modal-header-close" onClick={this.dismiss}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" style={{ margin: '3px 0 0 0' }} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@ const template = `
|
||||
<i class="fa fa-list"></i>
|
||||
</button>
|
||||
<button ng-click="ctrl.gridView()" ng-class="{active: ctrl.mode === 'grid'}">
|
||||
<i class="fa fa-th"></i>
|
||||
<icon name="table"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
@ -38,24 +38,25 @@
|
||||
|
||||
<div class="search-filter-box" ng-if="ctrl.isEditor || ctrl.hasEditPermissionInFolders">
|
||||
<a href="dashboard/new" class="search-filter-box-link">
|
||||
<icon name="'plus-square'" size="'xl'" style="margin-right: 8px;"></icon> New dashboard
|
||||
<icon name="'plus-square'" type="'mono'" size="'xl'" style="margin-right: 8px;"></icon> New dashboard
|
||||
</a>
|
||||
<a href="dashboards/folder/new" class="search-filter-box-link" ng-if="ctrl.isEditor">
|
||||
<icon name="'folder-plus'" size="'xl'" style="margin-right: 8px;"></icon> New folder
|
||||
<icon name="'folder-plus'" type="'mono'" size="'xl'" style="margin-right: 8px;"></icon> New folder
|
||||
</a>
|
||||
<a
|
||||
href="dashboard/import"
|
||||
class="search-filter-box-link"
|
||||
ng-if="ctrl.isEditor || ctrl.hasEditPermissionInFolders"
|
||||
>
|
||||
<icon name="'import'" size="'xl'" style="margin-right: 8px;"></icon> Import dashboard
|
||||
<icon name="'import'" type="'mono'" size="'xl'" style="margin-right: 8px;"></icon> Import dashboard
|
||||
</a>
|
||||
<a
|
||||
class="search-filter-box-link"
|
||||
target="_blank"
|
||||
href="https://grafana.com/dashboards?utm_source=grafana_search"
|
||||
>
|
||||
<icon name="'apps'" size="'xl'" style="margin-right: 8px;"></icon> Find dashboards on Grafana.com
|
||||
<icon name="'apps'" type="'mono'" size="'xl'" style="margin-right: 8px;"></icon> Find dashboards on
|
||||
Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -70,7 +70,7 @@ const UserListAdminPageUnConnected: React.FC<Props> = props => {
|
||||
<th>
|
||||
Seen
|
||||
<Tooltip placement="top" content="Time since user was seen using Grafana">
|
||||
<i className="fa fa-question-circle" />
|
||||
<Icon name="question-circle" />
|
||||
</Tooltip>
|
||||
</th>
|
||||
<th></th>
|
||||
@ -113,7 +113,7 @@ const renderUser = (user: UserDTO) => {
|
||||
{user.isAdmin && (
|
||||
<a href={editUrl}>
|
||||
<Tooltip placement="top" content="Grafana Admin">
|
||||
<i className="fa fa-shield" />
|
||||
<Icon name="shield" />
|
||||
</Tooltip>
|
||||
</a>
|
||||
)}
|
||||
|
@ -52,7 +52,11 @@ exports[`ServerStats Should render table with stats 1`] = `
|
||||
>
|
||||
<span
|
||||
className="page-header__logo"
|
||||
/>
|
||||
>
|
||||
<i
|
||||
className="fa fa-fw fa-warning css-1lgsh82"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className="page-header__info-block"
|
||||
>
|
||||
@ -99,6 +103,7 @@ exports[`ServerStats Should render table with stats 1`] = `
|
||||
className="css-vohy86"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<div />
|
||||
Admin
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -1,46 +1,52 @@
|
||||
<page-header model="navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<h3 class="page-sub-heading">Edit Organization</h3>
|
||||
<h3 class="page-sub-heading">Edit Organization</h3>
|
||||
|
||||
<form name="orgDetailsForm" class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-10">Name</span>
|
||||
<input type="text" required ng-model="org.name" class="gf-form-input max-width-14" >
|
||||
</div>
|
||||
<form name="orgDetailsForm" class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-10">Name</span>
|
||||
<input type="text" required ng-model="org.name" class="gf-form-input max-width-14" />
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-primary" ng-click="update()" ng-show="!createMode">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="gf-form-button-row">
|
||||
<button type="submit" class="btn btn-primary" ng-click="update()" ng-show="!createMode">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h3 class="page-heading">Organization Users</h3>
|
||||
<h3 class="page-heading">Organization Users</h3>
|
||||
|
||||
<table class="filter-table">
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr ng-repeat="orgUser in orgUsers">
|
||||
<td>{{orgUser.login}}</td>
|
||||
<td>{{orgUser.email}}</td>
|
||||
<td>
|
||||
<table class="filter-table">
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr ng-repeat="orgUser in orgUsers">
|
||||
<td>{{orgUser.login}}</td>
|
||||
<td>{{orgUser.email}}</td>
|
||||
<td>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-select-wrapper">
|
||||
<select type="text" ng-model="orgUser.role" class="gf-form-input max-width-8" ng-options="f for f in ['Viewer', 'Editor', 'Admin']" ng-change="updateOrgUser(orgUser)">
|
||||
</select>
|
||||
<select
|
||||
type="text"
|
||||
ng-model="orgUser.role"
|
||||
class="gf-form-input max-width-8"
|
||||
ng-options="f for f in ['Viewer', 'Editor', 'Admin']"
|
||||
ng-change="updateOrgUser(orgUser)"
|
||||
>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="removeOrgUser(orgUser)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="removeOrgUser(orgUser)" class="btn btn-danger btn-small">
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<footer />
|
||||
|
@ -108,7 +108,7 @@
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="removeOrgUser(org)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@ -138,7 +138,7 @@
|
||||
<td>{{session.browser}} on {{session.os}} {{session.osVersion}}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-small" ng-click="revokeUserSession(session.id)">
|
||||
<i class="fa fa-power-off"></i>
|
||||
<icon name="'power'" style="margin-top: -2px;"></icon>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@ -152,7 +152,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h3 class="page-heading">User status</h3>
|
||||
|
||||
<div class="gf-form-group">
|
||||
@ -177,7 +176,9 @@
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<button type="submit" class="btn btn-danger" ng-click="deleteUser(user)" ng-show="!createMode">Delete User</button>
|
||||
<button type="submit" class="btn btn-danger" ng-click="deleteUser(user)" ng-show="!createMode">
|
||||
Delete User
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,7 +30,7 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a ng-click="deleteOrg(org)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'" size="sm"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
// @ts-ignore
|
||||
import Highlighter from 'react-highlight-words';
|
||||
import classNames from 'classnames';
|
||||
import { AlertRule } from '../../types';
|
||||
import { Icon, IconName } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
rule: AlertRule;
|
||||
@ -24,19 +24,11 @@ class AlertRuleItem extends PureComponent<Props> {
|
||||
render() {
|
||||
const { rule, onTogglePause } = this.props;
|
||||
|
||||
const iconClassName = classNames({
|
||||
fa: true,
|
||||
'fa-play': rule.state === 'paused',
|
||||
'fa-pause': rule.state !== 'paused',
|
||||
});
|
||||
|
||||
const ruleUrl = `${rule.url}?panelId=${rule.panelId}&fullscreen&edit&tab=alert`;
|
||||
|
||||
return (
|
||||
<li className="alert-rule-item">
|
||||
<span className={`alert-rule-item__icon ${rule.stateClass}`}>
|
||||
<i className={rule.stateIcon} />
|
||||
</span>
|
||||
<Icon size="xl" name={rule.stateIcon as IconName} className={`alert-rule-item__icon ${rule.stateClass}`} />
|
||||
<div className="alert-rule-item__body">
|
||||
<div className="alert-rule-item__header">
|
||||
<div className="alert-rule-item__name">
|
||||
@ -56,10 +48,10 @@ class AlertRuleItem extends PureComponent<Props> {
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
onClick={onTogglePause}
|
||||
>
|
||||
<i className={iconClassName} />
|
||||
<Icon name={rule.state === 'paused' ? 'play' : 'pause'} />
|
||||
</button>
|
||||
<a className="btn btn-small btn-inverse alert-list__btn width-2" href={ruleUrl} title="Edit alert rule">
|
||||
<i className="gicon gicon-cog" />
|
||||
<Icon name="cog" />
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -4,13 +4,11 @@ exports[`Render should render component 1`] = `
|
||||
<li
|
||||
className="alert-rule-item"
|
||||
>
|
||||
<span
|
||||
<Icon
|
||||
className="alert-rule-item__icon state class"
|
||||
>
|
||||
<i
|
||||
className="icon"
|
||||
/>
|
||||
</span>
|
||||
name="icon"
|
||||
size="xl"
|
||||
/>
|
||||
<div
|
||||
className="alert-rule-item__body"
|
||||
>
|
||||
@ -67,8 +65,8 @@ exports[`Render should render component 1`] = `
|
||||
onClick={[MockFunction]}
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
>
|
||||
<i
|
||||
className="fa fa-pause"
|
||||
<Icon
|
||||
name="pause"
|
||||
/>
|
||||
</button>
|
||||
<a
|
||||
@ -76,8 +74,8 @@ exports[`Render should render component 1`] = `
|
||||
href="https://something.something.darkside?panelId=1&fullscreen&edit&tab=alert"
|
||||
title="Edit alert rule"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-cog"
|
||||
<Icon
|
||||
name="cog"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
<div ng-if="ctrl.panel.alert">
|
||||
<div class="alert alert-error m-b-2" ng-show="ctrl.error">
|
||||
<i class="fa fa-warning"></i> {{ctrl.error}}
|
||||
</div>
|
||||
<div class="alert alert-error m-b-2" ng-show="ctrl.error"><i class="fa fa-warning"></i> {{ctrl.error}}</div>
|
||||
<div class="panel-options-group">
|
||||
<div class="panel-options-group__body">
|
||||
<div class="gf-form-group">
|
||||
@ -9,33 +7,35 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Name</span>
|
||||
<input type="text" class="gf-form-input width-20" ng-model="ctrl.alert.name">
|
||||
<input type="text" class="gf-form-input width-20" ng-model="ctrl.alert.name" />
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9">Evaluate every</span>
|
||||
<input class="gf-form-input max-width-6" type="text" ng-model="ctrl.alert.frequency" ng-blur="ctrl.checkFrequency()">
|
||||
<input
|
||||
class="gf-form-input max-width-6"
|
||||
type="text"
|
||||
ng-model="ctrl.alert.frequency"
|
||||
ng-blur="ctrl.checkFrequency()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form max-width-11">
|
||||
<label class="gf-form-label width-5">For</label>
|
||||
<input type="text" class="gf-form-input max-width-6 gf-form-input--has-help-icon" ng-model="ctrl.alert.for"
|
||||
spellcheck='false' placeholder="5m">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input max-width-6 gf-form-input--has-help-icon"
|
||||
ng-model="ctrl.alert.for"
|
||||
spellcheck="false"
|
||||
placeholder="5m"
|
||||
/>
|
||||
<info-popover mode="right-absolute">
|
||||
If an alert rule has a configured For and the query violates the configured
|
||||
threshold it
|
||||
will first go from OK to Pending.
|
||||
Going from OK to Pending Grafana will not send any notifications. Once the alert
|
||||
rule
|
||||
has
|
||||
been firing for more than For duration, it will change to Alerting and send alert
|
||||
notifications.
|
||||
If an alert rule has a configured For and the query violates the configured threshold it will first go
|
||||
from OK to Pending. Going from OK to Pending Grafana will not send any notifications. Once the alert rule
|
||||
has been firing for more than For duration, it will change to Alerting and send alert notifications.
|
||||
</info-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.frequencyWarning">
|
||||
<label class="gf-form-label text-warning">
|
||||
<i
|
||||
class="fa fa-warning"></i> {{ctrl.frequencyWarning}}
|
||||
</label>
|
||||
<label class="gf-form-label text-warning"> <i class="fa fa-warning"></i> {{ctrl.frequencyWarning}} </label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -43,37 +43,57 @@
|
||||
<h4 class="section-heading">Conditions</h4>
|
||||
<div class="gf-form-inline" ng-repeat="conditionModel in ctrl.conditionModels">
|
||||
<div class="gf-form">
|
||||
<metric-segment-model css-class="query-keyword width-5" ng-if="$index"
|
||||
property="conditionModel.operator.type" options="ctrl.evalOperators"
|
||||
custom="false"></metric-segment-model>
|
||||
<metric-segment-model
|
||||
css-class="query-keyword width-5"
|
||||
ng-if="$index"
|
||||
property="conditionModel.operator.type"
|
||||
options="ctrl.evalOperators"
|
||||
custom="false"
|
||||
></metric-segment-model>
|
||||
<span class="gf-form-label query-keyword width-5" ng-if="$index===0">WHEN</span>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<query-part-editor class="gf-form-label query-part width-9"
|
||||
part="conditionModel.reducerPart"
|
||||
handle-event="ctrl.handleReducerPartEvent(conditionModel, $event)">
|
||||
<query-part-editor
|
||||
class="gf-form-label query-part width-9"
|
||||
part="conditionModel.reducerPart"
|
||||
handle-event="ctrl.handleReducerPartEvent(conditionModel, $event)"
|
||||
>
|
||||
</query-part-editor>
|
||||
<span class="gf-form-label query-keyword">OF</span>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<query-part-editor class="gf-form-label query-part" part="conditionModel.queryPart"
|
||||
handle-event="ctrl.handleQueryPartEvent(conditionModel, $event)">
|
||||
<query-part-editor
|
||||
class="gf-form-label query-part"
|
||||
part="conditionModel.queryPart"
|
||||
handle-event="ctrl.handleQueryPartEvent(conditionModel, $event)"
|
||||
>
|
||||
</query-part-editor>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<metric-segment-model property="conditionModel.evaluator.type" options="ctrl.evalFunctions"
|
||||
custom="false" css-class="query-keyword"
|
||||
on-change="ctrl.evaluatorTypeChanged(conditionModel.evaluator)"></metric-segment-model>
|
||||
<input class="gf-form-input max-width-9" type="number" step="any"
|
||||
ng-hide="conditionModel.evaluator.params.length === 0"
|
||||
ng-model="conditionModel.evaluator.params[0]"
|
||||
ng-change="ctrl.evaluatorParamsChanged()" />
|
||||
<label class="gf-form-label query-keyword"
|
||||
ng-show="conditionModel.evaluator.params.length === 2">TO</label>
|
||||
<input class="gf-form-input max-width-9" type="number" step="any"
|
||||
ng-if="conditionModel.evaluator.params.length === 2"
|
||||
ng-model="conditionModel.evaluator.params[1]"
|
||||
ng-change="ctrl.evaluatorParamsChanged()" />
|
||||
<metric-segment-model
|
||||
property="conditionModel.evaluator.type"
|
||||
options="ctrl.evalFunctions"
|
||||
custom="false"
|
||||
css-class="query-keyword"
|
||||
on-change="ctrl.evaluatorTypeChanged(conditionModel.evaluator)"
|
||||
></metric-segment-model>
|
||||
<input
|
||||
class="gf-form-input max-width-9"
|
||||
type="number"
|
||||
step="any"
|
||||
ng-hide="conditionModel.evaluator.params.length === 0"
|
||||
ng-model="conditionModel.evaluator.params[0]"
|
||||
ng-change="ctrl.evaluatorParamsChanged()"
|
||||
/>
|
||||
<label class="gf-form-label query-keyword" ng-show="conditionModel.evaluator.params.length === 2">TO</label>
|
||||
<input
|
||||
class="gf-form-input max-width-9"
|
||||
type="number"
|
||||
step="any"
|
||||
ng-if="conditionModel.evaluator.params.length === 2"
|
||||
ng-model="conditionModel.evaluator.params[1]"
|
||||
ng-change="ctrl.evaluatorParamsChanged()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
@ -107,8 +127,11 @@
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label query-keyword">SET STATE TO</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.alert.noDataState"
|
||||
ng-options="f.value as f.text for f in ctrl.noDataModes">
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.alert.noDataState"
|
||||
ng-options="f.value as f.text for f in ctrl.noDataModes"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -121,8 +144,11 @@
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label query-keyword">SET STATE TO</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.alert.executionErrorState"
|
||||
ng-options="f.value as f.text for f in ctrl.executionErrorModes">
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.alert.executionErrorState"
|
||||
ng-options="f.value as f.text for f in ctrl.executionErrorModes"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -142,27 +168,42 @@
|
||||
<span class="gf-form-label">
|
||||
<i class="{{nc.iconClass}}"></i>
|
||||
{{nc.name}} <span ng-if="nc.isDefault">(default)</span>
|
||||
<i class="fa fa-remove pointer muted" ng-click="ctrl.removeNotification(nc)" ng-if="nc.isDefault === false"></i>
|
||||
<icon
|
||||
name="'times'"
|
||||
class="pointer muted"
|
||||
ng-click="ctrl.removeNotification(nc)"
|
||||
ng-if="nc.isDefault === false"
|
||||
></icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<metric-segment segment="ctrl.addNotificationSegment"
|
||||
get-options="ctrl.getNotifications()"
|
||||
on-change="ctrl.notificationAdded()"></metric-segment>
|
||||
<metric-segment
|
||||
segment="ctrl.addNotificationSegment"
|
||||
get-options="ctrl.getNotifications()"
|
||||
on-change="ctrl.notificationAdded()"
|
||||
></metric-segment>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--v-stretch">
|
||||
<span class="gf-form-label width-8">Message</span>
|
||||
<textarea class="gf-form-input" rows="10" ng-model="ctrl.alert.message"
|
||||
placeholder="Notification message details..."></textarea>
|
||||
<textarea
|
||||
class="gf-form-input"
|
||||
rows="10"
|
||||
ng-model="ctrl.alert.message"
|
||||
placeholder="Notification message details..."
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-8">Tags</span>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline" ng-repeat="(name, value) in ctrl.alert.alertRuleTags">
|
||||
<label class="gf-form-label width-15">{{ name }}</label>
|
||||
<input class="gf-form-input width-15" placeholder="Tag value..."
|
||||
ng-model="ctrl.alert.alertRuleTags[name]" type="text"/>
|
||||
<input
|
||||
class="gf-form-input width-15"
|
||||
placeholder="Tag value..."
|
||||
ng-model="ctrl.alert.alertRuleTags[name]"
|
||||
type="text"
|
||||
/>
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" tabindex="1" ng-click="ctrl.removeAlertRuleTag(name)">
|
||||
<i class="fa fa-trash"></i>
|
||||
@ -172,10 +213,18 @@
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<input class="gf-form-input width-15" placeholder="New tag name..."
|
||||
ng-model="ctrl.newAlertRuleTag.name" type="text">
|
||||
<input class="gf-form-input width-15" placeholder="New tag value..."
|
||||
ng-model="ctrl.newAlertRuleTag.value" type="text">
|
||||
<input
|
||||
class="gf-form-input width-15"
|
||||
placeholder="New tag name..."
|
||||
ng-model="ctrl.newAlertRuleTag.name"
|
||||
type="text"
|
||||
/>
|
||||
<input
|
||||
class="gf-form-input width-15"
|
||||
placeholder="New tag value..."
|
||||
ng-model="ctrl.newAlertRuleTag.value"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
|
@ -35,7 +35,7 @@
|
||||
default
|
||||
</span>
|
||||
<a ng-click="ctrl.deleteNotification(notification.id)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -75,42 +75,42 @@ function getStateDisplayModel(state: string) {
|
||||
case 'ok': {
|
||||
return {
|
||||
text: 'OK',
|
||||
iconClass: 'icon-gf icon-gf-online',
|
||||
iconClass: 'heart',
|
||||
stateClass: 'alert-state-ok',
|
||||
};
|
||||
}
|
||||
case 'alerting': {
|
||||
return {
|
||||
text: 'ALERTING',
|
||||
iconClass: 'icon-gf icon-gf-critical',
|
||||
iconClass: 'heartbeat',
|
||||
stateClass: 'alert-state-critical',
|
||||
};
|
||||
}
|
||||
case 'no_data': {
|
||||
return {
|
||||
text: 'NO DATA',
|
||||
iconClass: 'fa fa-question',
|
||||
iconClass: 'question-circle',
|
||||
stateClass: 'alert-state-warning',
|
||||
};
|
||||
}
|
||||
case 'paused': {
|
||||
return {
|
||||
text: 'PAUSED',
|
||||
iconClass: 'fa fa-pause',
|
||||
iconClass: 'pause',
|
||||
stateClass: 'alert-state-paused',
|
||||
};
|
||||
}
|
||||
case 'pending': {
|
||||
return {
|
||||
text: 'PENDING',
|
||||
iconClass: 'fa fa-exclamation',
|
||||
iconClass: 'exclamation-triangle',
|
||||
stateClass: 'alert-state-warning',
|
||||
};
|
||||
}
|
||||
case 'unknown': {
|
||||
return {
|
||||
text: 'UNKNOWN',
|
||||
iconClass: 'fa fa-question',
|
||||
iconClass: 'question-circle',
|
||||
stateClass: 'alert-state-paused',
|
||||
};
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ describe('Alert rules', () => {
|
||||
state: 'alerting',
|
||||
stateAge: newStateDateAge,
|
||||
stateClass: 'alert-state-critical',
|
||||
stateIcon: 'icon-gf icon-gf-critical',
|
||||
stateIcon: 'heartbeat',
|
||||
stateText: 'ALERTING',
|
||||
url: '/d/ggHbN42mk/alerting-with-testdata',
|
||||
},
|
||||
@ -149,7 +149,7 @@ describe('Alert rules', () => {
|
||||
state: 'ok',
|
||||
stateAge: newStateDateAge,
|
||||
stateClass: 'alert-state-ok',
|
||||
stateIcon: 'icon-gf icon-gf-online',
|
||||
stateIcon: 'heart',
|
||||
stateText: 'OK',
|
||||
url: '/d/ggHbN42mk/alerting-with-testdata',
|
||||
},
|
||||
@ -168,7 +168,7 @@ describe('Alert rules', () => {
|
||||
state: 'ok',
|
||||
stateAge: newStateDateAge,
|
||||
stateClass: 'alert-state-ok',
|
||||
stateIcon: 'icon-gf icon-gf-online',
|
||||
stateIcon: 'heart',
|
||||
stateText: 'OK',
|
||||
url: '/d/ggHbN42mk/alerting-with-testdata',
|
||||
},
|
||||
@ -186,7 +186,7 @@ describe('Alert rules', () => {
|
||||
state: 'paused',
|
||||
stateAge: newStateDateAge,
|
||||
stateClass: 'alert-state-paused',
|
||||
stateIcon: 'fa fa-pause',
|
||||
stateIcon: 'pause',
|
||||
stateText: 'PAUSED',
|
||||
url: '/d/ggHbN42mk/alerting-with-testdata',
|
||||
},
|
||||
@ -207,7 +207,7 @@ describe('Alert rules', () => {
|
||||
state: 'ok',
|
||||
stateAge: newStateDateAge,
|
||||
stateClass: 'alert-state-ok',
|
||||
stateIcon: 'icon-gf icon-gf-online',
|
||||
stateIcon: 'heart',
|
||||
stateText: 'OK',
|
||||
url: '/d/ggHbN42mk/alerting-with-testdata',
|
||||
},
|
||||
|
@ -31,8 +31,7 @@
|
||||
<tbody>
|
||||
<tr ng-repeat="annotation in ctrl.annotations track by annotation.name">
|
||||
<td style="width:90%" ng-hide="annotation.builtIn" class="pointer" ng-click="ctrl.edit(annotation)">
|
||||
<i class="fa fa-comment" style="color:{{ annotation.iconColor }}"></i>
|
||||
{{ annotation.name }}
|
||||
<i class="fa fa-comment" style="color:{{ annotation.iconColor }}"></i> {{ annotation.name }}
|
||||
</td>
|
||||
<td style="width:90%" ng-show="annotation.builtIn" class="pointer" ng-click="ctrl.edit(annotation)">
|
||||
<i class="gicon gicon-annotation"></i>
|
||||
@ -53,7 +52,7 @@
|
||||
class="btn btn-danger btn-small"
|
||||
ng-hide="annotation.builtIn"
|
||||
>
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@ -62,7 +61,14 @@
|
||||
|
||||
<!-- empty list cta, there is always one built in query -->
|
||||
<div ng-if="ctrl.annotations.length === 1" class="p-t-2">
|
||||
<empty-list-cta title="ctrl.emptyListCta.title" buttonIcon="ctrl.emptyListCta.buttonIcon" buttonTitle="ctrl.emptyListCta.buttonTitle" infoBox="ctrl.emptyListCta.infoBox" infoBoxTitle="ctrl.emptyListCta.infoBoxTitle" on-click="ctrl.setupNew"/>
|
||||
<empty-list-cta
|
||||
title="ctrl.emptyListCta.title"
|
||||
buttonIcon="ctrl.emptyListCta.buttonIcon"
|
||||
buttonTitle="ctrl.emptyListCta.buttonTitle"
|
||||
infoBox="ctrl.emptyListCta.infoBox"
|
||||
infoBoxTitle="ctrl.emptyListCta.infoBoxTitle"
|
||||
on-click="ctrl.setupNew"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
apiKey: string;
|
||||
@ -10,12 +11,12 @@ export const ApiKeysAddedModal = (props: Props) => {
|
||||
<div className="modal-body">
|
||||
<div className="modal-header">
|
||||
<h2 className="modal-header-title">
|
||||
<i className="fa fa-key" />
|
||||
<Icon name="key-skeleton-alt" />
|
||||
<span className="p-l-1">API Key Created</span>
|
||||
</h2>
|
||||
|
||||
<a className="modal-header-close" ng-click="dismiss();">
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +13,15 @@ import ApiKeysAddedModal from './ApiKeysAddedModal';
|
||||
import config from 'app/core/config';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { DeleteButton, EventsWithValidation, FormLabel, LegacyForms, Switch, ValidationEvents } from '@grafana/ui';
|
||||
import {
|
||||
DeleteButton,
|
||||
EventsWithValidation,
|
||||
FormLabel,
|
||||
LegacyForms,
|
||||
Switch,
|
||||
ValidationEvents,
|
||||
Icon,
|
||||
} from '@grafana/ui';
|
||||
const { Input } = LegacyForms;
|
||||
import { dateTime, isDateTime, NavModel } from '@grafana/data';
|
||||
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
||||
@ -181,7 +189,7 @@ export class ApiKeysPage extends PureComponent<Props, any> {
|
||||
<SlideDown in={isAdding}>
|
||||
<div className="cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
|
||||
<i className="fa fa-close" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
<h5>Add API Key</h5>
|
||||
<form className="gf-form-group" onSubmit={this.onAddApiKey}>
|
||||
|
@ -10,8 +10,8 @@ exports[`Render should render component 1`] = `
|
||||
<h2
|
||||
className="modal-header-title"
|
||||
>
|
||||
<i
|
||||
className="fa fa-key"
|
||||
<Icon
|
||||
name="key-skeleton-alt"
|
||||
/>
|
||||
<span
|
||||
className="p-l-1"
|
||||
@ -23,8 +23,8 @@ exports[`Render should render component 1`] = `
|
||||
className="modal-header-close"
|
||||
ng-click="dismiss();"
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -53,8 +53,8 @@ exports[`Render should render CTA if there are no API keys 1`] = `
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</button>
|
||||
<h5>
|
||||
|
@ -11,15 +11,22 @@
|
||||
class="btn btn-primary"
|
||||
ng-click="ctrl.setupNew()"
|
||||
ng-if="ctrl.dashboard.links.length > 0"
|
||||
ng-hide="ctrl.mode === 'edit' || ctrl.mode === 'new'">
|
||||
New
|
||||
</a
|
||||
ng-hide="ctrl.mode === 'edit' || ctrl.mode === 'new'"
|
||||
>
|
||||
New
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.mode == 'list'">
|
||||
<div ng-if="ctrl.dashboard.links.length === 0">
|
||||
<empty-list-cta on-click="ctrl.setupNew" title="ctrl.emptyListCta.title" buttonIcon="ctrl.emptyListCta.buttonIcon" buttonTitle="ctrl.emptyListCta.buttonTitle" infoBox="ctrl.emptyListCta.infoBox" infoBoxTitle="ctrl.emptyListCta.infoBoxTitle"/>
|
||||
<empty-list-cta
|
||||
on-click="ctrl.setupNew"
|
||||
title="ctrl.emptyListCta.title"
|
||||
buttonIcon="ctrl.emptyListCta.buttonIcon"
|
||||
buttonTitle="ctrl.emptyListCta.buttonTitle"
|
||||
infoBox="ctrl.emptyListCta.infoBox"
|
||||
infoBoxTitle="ctrl.emptyListCta.infoBoxTitle"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.dashboard.links.length > 0">
|
||||
@ -62,7 +69,7 @@
|
||||
</td>
|
||||
<td style="width: 1%">
|
||||
<a ng-click="ctrl.deleteLink($index)" class="btn btn-danger btn-small" ng-hide="annotation.builtIn">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -112,7 +112,7 @@ export const OverrideFieldConfigEditor: React.FC<Props> = props => {
|
||||
const renderAddOverride = () => {
|
||||
return (
|
||||
<ValuePicker
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
label="Add override"
|
||||
variant="secondary"
|
||||
options={fieldMatchersUI
|
||||
|
@ -115,7 +115,7 @@ export const OverrideEditor: React.FC<OverrideEditorProps> = ({
|
||||
<div className={styles.propertyPickerWrapper}>
|
||||
<ValuePicker
|
||||
label="Set config property"
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
options={configPropertiesOptions}
|
||||
variant={'link'}
|
||||
onChange={o => {
|
||||
|
@ -6,7 +6,7 @@
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="ctrl.dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@ const template = `
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="ctrl.dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -7,7 +7,7 @@ import classNames from 'classnames';
|
||||
import { css } from 'emotion';
|
||||
|
||||
import { ExploreId, ExploreItemState } from 'app/types/explore';
|
||||
import { ToggleButtonGroup, ToggleButton, Tooltip, LegacyForms, SetInterval } from '@grafana/ui';
|
||||
import { ToggleButtonGroup, ToggleButton, Tooltip, LegacyForms, SetInterval, Icon } from '@grafana/ui';
|
||||
const { ButtonSelect } = LegacyForms;
|
||||
import { RawTimeRange, TimeZone, TimeRange, DataQuery, ExploreMode } from '@grafana/data';
|
||||
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
||||
@ -202,14 +202,21 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
||||
<div className="explore-toolbar-header-title">
|
||||
{exploreId === 'left' && (
|
||||
<span className="navbar-page-btn">
|
||||
<i className="gicon gicon-explore" />
|
||||
<Icon
|
||||
name="compass"
|
||||
size="xl"
|
||||
className={css`
|
||||
margin-right: 6px;
|
||||
margin-bottom: 3px;
|
||||
`}
|
||||
/>
|
||||
Explore
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{splitted && (
|
||||
<a className="explore-toolbar-header-close" onClick={() => closeSplit(exploreId)}>
|
||||
<i className="fa fa-times fa-fw" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@ -261,7 +268,7 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
||||
<div className="explore-toolbar-content-item">
|
||||
<Tooltip content={'Return to panel'} placement="bottom">
|
||||
<button className={panelReturnClasses} onClick={() => this.returnToPanel()}>
|
||||
<i className="fa fa-arrow-left" />
|
||||
<Icon name="arrow-left" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{originDashboardIsEditable && (
|
||||
@ -281,7 +288,8 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
||||
splitted={splitted}
|
||||
title="Split"
|
||||
onClick={split}
|
||||
iconClassName="fa fa-fw fa-columns icon-margin-right"
|
||||
icon="columns"
|
||||
iconClassName="icon-margin-right"
|
||||
disabled={isLive}
|
||||
/>
|
||||
</div>
|
||||
@ -307,7 +315,8 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
||||
splitted={splitted}
|
||||
title="Clear All"
|
||||
onClick={this.onClearAll}
|
||||
iconClassName="fa fa-fw fa-trash icon-margin-right"
|
||||
icon="trash-alt"
|
||||
iconClassName="icon-margin-right"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -128,11 +128,8 @@ export function LiveTailButton(props: LiveTailButtonProps) {
|
||||
[styles.isLive]: isLive && !isPaused,
|
||||
[styles.isPaused]: isLive && isPaused,
|
||||
})}
|
||||
iconClassName={classNames(
|
||||
'fa',
|
||||
isPaused || !isLive ? 'fa-play' : 'fa-pause',
|
||||
isLive && 'icon-brand-gradient'
|
||||
)}
|
||||
icon={!isLive ? 'play' : 'pause'}
|
||||
iconClassName={isLive && 'icon-brand-gradient'}
|
||||
onClick={onClickMain}
|
||||
title={'\xa0Live'}
|
||||
/>
|
||||
|
@ -30,10 +30,10 @@ describe('QueryRowActions', () => {
|
||||
});
|
||||
it('should change icon to fa-eye-slash when query row result is hidden', () => {
|
||||
const wrapper = setup({ isDisabled: true });
|
||||
expect(wrapper.find('i.fa-eye-slash')).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Enable query' })).toHaveLength(1);
|
||||
});
|
||||
it('should change icon to fa-eye when query row result is not hidden', () => {
|
||||
const wrapper = setup({ isDisabled: false });
|
||||
expect(wrapper.find('i.fa-eye')).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Disable query' })).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
function formatLatency(value: number) {
|
||||
return `${(value / 1000).toFixed(1)}s`;
|
||||
@ -34,7 +35,7 @@ export function QueryRowActions(props: Props) {
|
||||
className="gf-form-label gf-form-label--btn"
|
||||
onClick={onClickToggleEditorMode}
|
||||
>
|
||||
<i className="fa fa-pencil" />
|
||||
<Icon name="pen" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
@ -48,14 +49,14 @@ export function QueryRowActions(props: Props) {
|
||||
disabled={isNotStarted}
|
||||
className="gf-form-label gf-form-label--btn"
|
||||
onClick={onClickToggleDisabled}
|
||||
title="Disable/enable query"
|
||||
title={isDisabled ? 'Enable query' : 'Disable query'}
|
||||
>
|
||||
<i className={isDisabled ? 'fa fa-eye-slash' : 'fa fa-eye'} />
|
||||
<Icon name={isDisabled ? 'eye' : 'eye-slash'} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<button className="gf-form-label gf-form-label--btn" onClick={onClickRemoveButton} title="Remove query">
|
||||
<i className="fa fa-minus" />
|
||||
<Icon name="minus" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { forwardRef } from 'react';
|
||||
import { IconName, Icon } from '@grafana/ui';
|
||||
|
||||
export enum IconSide {
|
||||
left = 'left',
|
||||
@ -10,6 +11,7 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||
title: string;
|
||||
onClick: () => void;
|
||||
buttonClassName?: string;
|
||||
icon?: IconName;
|
||||
iconClassName?: string;
|
||||
iconSide?: IconSide;
|
||||
disabled?: boolean;
|
||||
@ -25,7 +27,17 @@ export const ResponsiveButton = forwardRef<HTMLDivElement, Props>((props, ref) =
|
||||
};
|
||||
|
||||
props = { ...defaultProps, ...props };
|
||||
const { title, onClick, buttonClassName, iconClassName, splitted, iconSide, disabled, ...divElementProps } = props;
|
||||
const {
|
||||
title,
|
||||
onClick,
|
||||
buttonClassName,
|
||||
icon,
|
||||
iconClassName,
|
||||
splitted,
|
||||
iconSide,
|
||||
disabled,
|
||||
...divElementProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div ref={ref} {...divElementProps}>
|
||||
@ -34,9 +46,9 @@ export const ResponsiveButton = forwardRef<HTMLDivElement, Props>((props, ref) =
|
||||
onClick={onClick}
|
||||
disabled={disabled || false}
|
||||
>
|
||||
{iconClassName && iconSide === IconSide.left ? <i className={`${iconClassName}`} /> : null}
|
||||
{icon && iconSide === IconSide.left ? <Icon name={icon} className={iconClassName} /> : null}
|
||||
<span className="btn-title">{!splitted ? formatBtnTitle(title, iconSide) : ''}</span>
|
||||
{iconClassName && iconSide === IconSide.right ? <i className={`${iconClassName}`} /> : null}
|
||||
{icon && iconSide === IconSide.right ? <Icon name={icon} className={iconClassName} /> : null}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -10,7 +10,7 @@ import { stylesFactory, withTheme } from '@grafana/ui';
|
||||
//Types
|
||||
import { RichHistoryQuery, ExploreId } from 'app/types/explore';
|
||||
import { SelectableValue, GrafanaTheme } from '@grafana/data';
|
||||
import { TabsBar, Tab, TabContent, Themeable, CustomScrollbar, IconName } from '@grafana/ui';
|
||||
import { TabsBar, Tab, TabContent, Themeable, CustomScrollbar, IconName, Icon } from '@grafana/ui';
|
||||
|
||||
//Components
|
||||
import { RichHistorySettings } from './RichHistorySettings';
|
||||
@ -169,7 +169,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
|
||||
height={height}
|
||||
/>
|
||||
),
|
||||
icon: 'fa fa-history',
|
||||
icon: 'history',
|
||||
};
|
||||
|
||||
const StarredTab = {
|
||||
@ -186,7 +186,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
|
||||
exploreId={exploreId}
|
||||
/>
|
||||
),
|
||||
icon: 'fa fa-star',
|
||||
icon: 'star',
|
||||
};
|
||||
|
||||
const SettingsTab = {
|
||||
@ -203,7 +203,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
|
||||
deleteRichHistory={deleteRichHistory}
|
||||
/>
|
||||
),
|
||||
icon: 'gicon gicon-preferences',
|
||||
icon: 'sliders-v-alt',
|
||||
};
|
||||
|
||||
let tabs = [QueriesTab, StarredTab, SettingsTab];
|
||||
@ -220,7 +220,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
|
||||
/>
|
||||
))}
|
||||
<div className={styles.close} onClick={onClose}>
|
||||
<i className="fa fa-times" title="Close query history" />
|
||||
<Icon name="times" title="Close query history" />
|
||||
</div>
|
||||
</TabsBar>
|
||||
<CustomScrollbar
|
||||
|
@ -79,37 +79,29 @@ describe('RichHistoryCard', () => {
|
||||
describe('commenting', () => {
|
||||
it('should render comment, if comment present', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.find({ 'aria-label': 'Query comment' })).toHaveLength(1);
|
||||
expect(wrapper.find({ 'aria-label': 'Query comment' }).hostNodes()).toHaveLength(1);
|
||||
expect(wrapper.find({ 'aria-label': 'Query comment' }).text()).toEqual('test comment');
|
||||
});
|
||||
it('should have title "Edit comment" at comment icon, if comment present', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Add comment' })).toHaveLength(0);
|
||||
expect(wrapper.find({ title: 'Edit comment' }).hostNodes()).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Add comment' }).hostNodes()).toHaveLength(0);
|
||||
});
|
||||
it('should have title "Add comment" at comment icon, if no comment present', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find({ title: 'Add comment' })).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(0);
|
||||
expect(wrapper.find({ title: 'Add comment' }).hostNodes()).toHaveLength(1);
|
||||
expect(wrapper.find({ title: 'Edit comment' }).hostNodes()).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('starring', () => {
|
||||
it('should have title "Star query", if not starred', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find({ title: 'Star query' })).toHaveLength(1);
|
||||
});
|
||||
it('should render fa-star-o icon, if not starred', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find({ title: 'Star query' }).hasClass('fa-star-o')).toBe(true);
|
||||
expect(wrapper.find({ title: 'Star query' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
it('should have title "Unstar query", if not starred', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.find({ title: 'Unstar query' })).toHaveLength(1);
|
||||
});
|
||||
it('should have fa-star icon, if not starred', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.find({ title: 'Unstar query' }).hasClass('fa-star')).toBe(true);
|
||||
expect(wrapper.find({ title: 'Unstar query' }).hostNodes()).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { css, cx } from 'emotion';
|
||||
import { stylesFactory, useTheme, Forms, Button } from '@grafana/ui';
|
||||
import { stylesFactory, useTheme, Forms, Button, Icon } from '@grafana/ui';
|
||||
import { GrafanaTheme, AppEvents, DataSourceApi } from '@grafana/data';
|
||||
import { RichHistoryQuery, ExploreId } from 'app/types/explore';
|
||||
import { copyStringToClipboard, createUrlFromRichHistory, createDataQuery } from 'app/core/utils/richHistory';
|
||||
@ -76,9 +76,8 @@ const getStyles = stylesFactory((theme: GrafanaTheme, isRemoved: boolean) => {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
font-size: ${theme.typography.size.base};
|
||||
i {
|
||||
margin: ${theme.spacing.xs};
|
||||
cursor: pointer;
|
||||
svg {
|
||||
margin-left: ${theme.spacing.sm};
|
||||
}
|
||||
`,
|
||||
queryContainer: css`
|
||||
@ -212,19 +211,20 @@ export function RichHistoryCard(props: Props) {
|
||||
|
||||
const queryActionButtons = (
|
||||
<div className={styles.queryActionButtons}>
|
||||
<i
|
||||
className="fa fa-fw fa-comment-o"
|
||||
<Icon
|
||||
name="comment-alt"
|
||||
onClick={toggleActiveUpdateComment}
|
||||
title={query.comment?.length > 0 ? 'Edit comment' : 'Add comment'}
|
||||
></i>
|
||||
<i className="fa fa-fw fa-copy" onClick={onCopyQuery} title="Copy query to clipboard"></i>
|
||||
{!isRemoved && <i className="fa fa-fw fa-link" onClick={onCreateLink} title="Copy link to clipboard"></i>}
|
||||
<i className={'fa fa-trash'} title={'Delete query'} onClick={onDeleteQuery}></i>
|
||||
<i
|
||||
className={cx('fa fa-fw', query.starred ? 'fa-star starred' : 'fa-star-o')}
|
||||
/>
|
||||
<Icon name="copy" onClick={onCopyQuery} title="Copy query to clipboard" />
|
||||
{!isRemoved && <Icon name="link" onClick={onCreateLink} title="Copy link to clipboard" />}
|
||||
<Icon name="trash-alt" title={'Delete query'} onClick={onDeleteQuery} />
|
||||
<Icon
|
||||
name={query.starred ? 'favorite' : 'star'}
|
||||
type={query.starred ? 'mono' : 'default'}
|
||||
onClick={onStarrQuery}
|
||||
title={query.starred ? 'Unstar query' : 'Star query'}
|
||||
></i>
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -40,7 +40,8 @@ export function RunButton(props: Props) {
|
||||
'navbar-button--danger': loading,
|
||||
'btn--radius-right-0': showDropdown,
|
||||
})}
|
||||
iconClassName={loading ? 'fa fa-spinner fa-fw fa-spin run-icon' : 'fa fa-refresh fa-fw'}
|
||||
icon={loading ? 'fa fa-spinner' : 'sync'}
|
||||
iconClassName={loading && ' fa-spin run-icon'}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -12,8 +12,8 @@ exports[`QueryRowActions should render component 1`] = `
|
||||
className="gf-form-label gf-form-label--btn"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-pencil"
|
||||
<Icon
|
||||
name="pen"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
@ -35,10 +35,10 @@ exports[`QueryRowActions should render component 1`] = `
|
||||
className="gf-form-label gf-form-label--btn"
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
title="Disable/enable query"
|
||||
title="Disable query"
|
||||
>
|
||||
<i
|
||||
className="fa fa-eye"
|
||||
<Icon
|
||||
name="eye-slash"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
@ -50,8 +50,8 @@ exports[`QueryRowActions should render component 1`] = `
|
||||
onClick={[Function]}
|
||||
title="Remove query"
|
||||
>
|
||||
<i
|
||||
className="fa fa-minus"
|
||||
<Icon
|
||||
name="minus"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="ctrl.dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<span style="position: relative;">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Find dashboards by name"
|
||||
placeholder="Search dashboards by name"
|
||||
tabindex="1"
|
||||
ng-keydown="ctrl.keyDown($event)"
|
||||
ng-model="ctrl.query.query"
|
||||
|
@ -46,7 +46,7 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a ng-click="ctrl.removePlaylist(playlist)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
<td>{{ session.browser }} on {{ session.os }} {{ session.osVersion }}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-small" ng-click="ctrl.revokeUserSession(session.id)">
|
||||
<i class="fa fa-power-off"></i>
|
||||
<icon name="'power'" style="margin-top: -2px;"></icon>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -66,7 +66,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
|
||||
<td>{group.groupId}</td>
|
||||
<td style={{ width: '1%' }}>
|
||||
<a className="btn btn-danger btn-small" onClick={() => this.onRemoveGroup(group)}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@ -95,7 +95,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
|
||||
<SlideDown in={isAdding}>
|
||||
<div className="cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
|
||||
<i className="fa fa-close" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
<h5>Add External Group</h5>
|
||||
<form className="gf-form-inline" onSubmit={this.onAddGroup}>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import { SlideDown } from 'app/core/components/Animations/SlideDown';
|
||||
import { UserPicker } from 'app/core/components/Select/UserPicker';
|
||||
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
|
||||
@ -97,7 +98,7 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
<SlideDown in={isAdding}>
|
||||
<div className="cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={this.onToggleAdding}>
|
||||
<i className="fa fa-close" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
<h5>Add team member</h5>
|
||||
<div className="gf-form-inline">
|
||||
|
@ -33,8 +33,8 @@ exports[`Render should render component 1`] = `
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</button>
|
||||
<h5>
|
||||
@ -124,8 +124,8 @@ exports[`Render should render groups table 1`] = `
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</button>
|
||||
<h5>
|
||||
@ -198,8 +198,8 @@ exports[`Render should render groups table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</a>
|
||||
</td>
|
||||
@ -221,8 +221,8 @@ exports[`Render should render groups table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</a>
|
||||
</td>
|
||||
@ -244,8 +244,8 @@ exports[`Render should render groups table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</a>
|
||||
</td>
|
||||
|
@ -37,8 +37,8 @@ exports[`Render should render component 1`] = `
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</button>
|
||||
<h5>
|
||||
@ -131,8 +131,8 @@ exports[`Render should render team members 1`] = `
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</button>
|
||||
<h5>
|
||||
|
@ -94,7 +94,7 @@
|
||||
class="btn btn-danger btn-small"
|
||||
aria-label="{{::selectors.tableRowRemoveButtons(variable.name)}}"
|
||||
>
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -2,6 +2,7 @@ import React, { createRef, PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Invitee } from 'app/types';
|
||||
import { revokeInvite } from './state/actions';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
invitee: Invitee;
|
||||
@ -40,7 +41,7 @@ class InviteeRow extends PureComponent<Props> {
|
||||
</td>
|
||||
<td>
|
||||
<button className="btn btn-danger btn-small" onClick={() => revokeInvite(invitee.code)}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { FC } from 'react';
|
||||
import { OrgUser } from 'app/types';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
users: OrgUser[];
|
||||
@ -55,7 +56,7 @@ const UsersTable: FC<Props> = props => {
|
||||
</td>
|
||||
<td>
|
||||
<div onClick={() => onRemoveUser(user)} className="btn btn-danger btn-small">
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -127,8 +127,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -193,8 +193,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -259,8 +259,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -325,8 +325,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -391,8 +391,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -457,8 +457,8 @@ exports[`Render should render users table 1`] = `
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
<Icon
|
||||
name="times"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -3,6 +3,7 @@ import { e2e } from '@grafana/e2e';
|
||||
import EmptyListCTA from '../../../core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { QueryVariableModel, VariableModel } from '../../templating/types';
|
||||
import { toVariableIdentifier, VariableIdentifier } from '../state/types';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
variables: VariableModel[];
|
||||
@ -148,7 +149,7 @@ export class VariableEditorList extends PureComponent<Props> {
|
||||
variable.name
|
||||
)}
|
||||
>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,34 +1,51 @@
|
||||
<div class="modal-body" ng-cloak>
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-header-title">
|
||||
<i class="fa {{icon}}"></i>
|
||||
<span class="p-l-1">
|
||||
{{title}}
|
||||
</span>
|
||||
</h2>
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-header-title">
|
||||
<i class="fa {{icon}}"></i>
|
||||
<span class="p-l-1">
|
||||
{{title}}
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
<a class="modal-header-close" ng-click="dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</div>
|
||||
<a class="modal-header-close" ng-click="dismiss();">
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="modal-content text-center">
|
||||
|
||||
<div class="confirm-modal-text">
|
||||
{{text}}
|
||||
<div ng-if="text2 && text2htmlBind" class="confirm-modal-text2" ng-bind-html="text2"></div>
|
||||
<div class="modal-content text-center">
|
||||
<div class="confirm-modal-text">
|
||||
{{text}}
|
||||
<div ng-if="text2 && text2htmlBind" class="confirm-modal-text2" ng-bind-html="text2"></div>
|
||||
<div ng-if="text2 && !text2htmlBind" class="confirm-modal-text2">{{text2}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-content-confirm-text" ng-if="confirmText">
|
||||
<input type="text" class="gf-form-input width-16" style="display: inline-block;" placeholder="Type {{confirmText}} to confirm" ng-model="confirmInput" ng-change="updateConfirmText(confirmInput)">
|
||||
</div>
|
||||
|
||||
<div class="confirm-modal-buttons">
|
||||
<button ng-show="onAltAction" type="button" class="btn btn-primary" ng-click="dismiss();onAltAction();">{{altActionText}}</button>
|
||||
<button ng-show="onConfirm" type="button" class="btn btn-danger" ng-click="onConfirm();dismiss();" ng-disabled="!confirmTextValid" give-focus="true" aria-label={{selectors.delete}}>{{yesText}}</button>
|
||||
<button type="button" class="btn btn-inverse" ng-click="dismiss()">{{noText}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-content-confirm-text" ng-if="confirmText">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-16"
|
||||
style="display: inline-block;"
|
||||
placeholder="Type {{confirmText}} to confirm"
|
||||
ng-model="confirmInput"
|
||||
ng-change="updateConfirmText(confirmInput)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="confirm-modal-buttons">
|
||||
<button ng-show="onAltAction" type="button" class="btn btn-primary" ng-click="dismiss();onAltAction();">
|
||||
{{altActionText}}
|
||||
</button>
|
||||
<button
|
||||
ng-show="onConfirm"
|
||||
type="button"
|
||||
class="btn btn-danger"
|
||||
ng-click="onConfirm();dismiss();"
|
||||
ng-disabled="!confirmTextValid"
|
||||
give-focus="true"
|
||||
aria-label="{{selectors.delete}}"
|
||||
>
|
||||
{{yesText}}
|
||||
</button>
|
||||
<button type="button" class="btn btn-inverse" ng-click="dismiss()">{{noText}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
</h2>
|
||||
|
||||
<button class="tabbed-view-close-btn" ng-click="dismiss()">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -67,7 +67,7 @@ export const DataLinks = (props: Props) => {
|
||||
className={css`
|
||||
margin-right: 10px;
|
||||
`}
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
const newDataLinks = [...(value || []), { field: '', url: '' }];
|
||||
|
@ -1,16 +1,33 @@
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="false" has-text-edit-mode="ctrl.target.queryType === 'Application Insights'">
|
||||
<query-editor-row
|
||||
query-ctrl="ctrl"
|
||||
can-collapse="false"
|
||||
has-text-edit-mode="ctrl.target.queryType === 'Application Insights'"
|
||||
>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Service</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
|
||||
<select class="gf-form-input service-dropdown" ng-model="ctrl.target.queryType" ng-options="f as f for f in ['Application Insights', 'Azure Monitor', 'Azure Log Analytics']"
|
||||
ng-change="ctrl.onQueryTypeChange()"></select>
|
||||
<select
|
||||
class="gf-form-input service-dropdown"
|
||||
ng-model="ctrl.target.queryType"
|
||||
ng-options="f as f for f in ['Application Insights', 'Azure Monitor', 'Azure Log Analytics']"
|
||||
ng-change="ctrl.onQueryTypeChange()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.target.queryType === 'Azure Monitor' || ctrl.target.queryType === 'Azure Log Analytics'">
|
||||
<div
|
||||
class="gf-form"
|
||||
ng-if="ctrl.target.queryType === 'Azure Monitor' || ctrl.target.queryType === 'Azure Log Analytics'"
|
||||
>
|
||||
<label class="gf-form-label query-keyword width-9">Subscription</label>
|
||||
<gf-form-dropdown model="ctrl.target.subscription" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getSubscriptions()" on-change="ctrl.onSubscriptionChange()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.subscription"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getSubscriptions()"
|
||||
on-change="ctrl.onSubscriptionChange()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -21,20 +38,38 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Resource Group</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureMonitor.resourceGroup" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getResourceGroups($query)" on-change="ctrl.onResourceGroupChange()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureMonitor.resourceGroup"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getResourceGroups($query)"
|
||||
on-change="ctrl.onResourceGroupChange()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Namespace</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureMonitor.metricDefinition" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getMetricDefinitions($query)" on-change="ctrl.onMetricDefinitionChange()" css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureMonitor.metricDefinition"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getMetricDefinitions($query)"
|
||||
on-change="ctrl.onMetricDefinitionChange()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Resource Name</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureMonitor.resourceName" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getResourceNames($query)" on-change="ctrl.onResourceNameChange()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureMonitor.resourceName"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getResourceNames($query)"
|
||||
on-change="ctrl.onResourceNameChange()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -44,21 +79,37 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Metric Namespace</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureMonitor.metricNamespace" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getMetricNamespaces($query)" on-change="ctrl.onMetricNamespacesChange()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureMonitor.metricNamespace"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getMetricNamespaces($query)"
|
||||
on-change="ctrl.onMetricNamespacesChange()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Metric</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureMonitor.metricName" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getMetricNames($query)" on-change="ctrl.onMetricNameChange()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureMonitor.metricName"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getMetricNames($query)"
|
||||
on-change="ctrl.onMetricNameChange()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow aggregation-dropdown-wrapper">
|
||||
<label class="gf-form-label query-keyword width-9">Aggregation</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
|
||||
<select class="gf-form-input width-11" ng-model="ctrl.target.azureMonitor.aggregation" ng-options="f as f for f in ctrl.target.azureMonitor.aggOptions"
|
||||
ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input width-11"
|
||||
ng-model="ctrl.target.azureMonitor.aggregation"
|
||||
ng-options="f as f for f in ctrl.target.azureMonitor.aggOptions"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -66,8 +117,12 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Time Grain</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent timegrainunit-dropdown-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.target.azureMonitor.timeGrain" ng-options="f.value as f.text for f in ctrl.target.azureMonitor.timeGrains"
|
||||
ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.azureMonitor.timeGrain"
|
||||
ng-options="f.value as f.text for f in ctrl.target.azureMonitor.timeGrains"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-show="ctrl.target.azureMonitor.timeGrain.trim() === 'auto'">
|
||||
@ -82,19 +137,35 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Dimension</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
|
||||
<select class="gf-form-input min-width-12" ng-model="ctrl.target.azureMonitor.dimension" ng-options="f.value as f.text for f in ctrl.target.azureMonitor.dimensions"
|
||||
ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input min-width-12"
|
||||
ng-model="ctrl.target.azureMonitor.dimension"
|
||||
ng-options="f.value as f.text for f in ctrl.target.azureMonitor.dimensions"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-3">eq</label>
|
||||
<input type="text" class="gf-form-input width-17" ng-model="ctrl.target.azureMonitor.dimensionFilter"
|
||||
spellcheck="false" placeholder="auto" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-17"
|
||||
ng-model="ctrl.target.azureMonitor.dimensionFilter"
|
||||
spellcheck="false"
|
||||
placeholder="auto"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Top</label>
|
||||
<input type="text" class="gf-form-input width-3" ng-model="ctrl.target.azureMonitor.top"
|
||||
spellcheck="false" placeholder="10" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-3"
|
||||
ng-model="ctrl.target.azureMonitor.top"
|
||||
spellcheck="false"
|
||||
placeholder="10"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -103,8 +174,14 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Legend Format</label>
|
||||
<input type="text" class="gf-form-input width-30" ng-model="ctrl.target.azureMonitor.alias" spellcheck="false"
|
||||
placeholder="alias patterns (see help for more info)" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-30"
|
||||
ng-model="ctrl.target.azureMonitor.alias"
|
||||
spellcheck="false"
|
||||
placeholder="alias patterns (see help for more info)"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -117,8 +194,14 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Workspace</label>
|
||||
<gf-form-dropdown model="ctrl.target.azureLogAnalytics.workspace" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getWorkspaces()" on-change="ctrl.refresh()" css-class="min-width-12">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.azureLogAnalytics.workspace"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getWorkspaces()"
|
||||
on-change="ctrl.refresh()"
|
||||
css-class="min-width-12"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
<div class="gf-form">
|
||||
<div class="width-1"></div>
|
||||
@ -150,8 +233,12 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">Format As</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.azureLogAnalytics.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||
ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input gf-size-auto"
|
||||
ng-model="ctrl.target.azureLogAnalytics.resultFormat"
|
||||
ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
@ -211,7 +298,6 @@
|
||||
- | summarize count() by Category, bin(TimeGenerated, $__interval)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.target.queryType === 'Application Insights'">
|
||||
@ -219,16 +305,25 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Metric</label>
|
||||
<gf-form-dropdown model="ctrl.target.appInsights.metricName" allow-custom="true" lookup-text="true"
|
||||
get-options="ctrl.getAppInsightsMetricNames($query)" on-change="ctrl.onAppInsightsMetricNameChange()"
|
||||
css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.appInsights.metricName"
|
||||
allow-custom="true"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getAppInsightsMetricNames($query)"
|
||||
on-change="ctrl.onAppInsightsMetricNameChange()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Aggregation</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
|
||||
<select class="gf-form-input" ng-model="ctrl.target.appInsights.aggregation" ng-options="f as f for f in ctrl.target.appInsights.aggOptions"
|
||||
ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.appInsights.aggregation"
|
||||
ng-options="f as f for f in ctrl.target.appInsights.aggOptions"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -238,20 +333,35 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Group By</label>
|
||||
<gf-form-dropdown allow-custom="true" ng-hide="ctrl.target.appInsights.dimension !== 'none'" model="ctrl.target.appInsights.dimension"
|
||||
lookup-text="true" get-options="ctrl.getAppInsightsGroupBySegments($query)" on-change="ctrl.refresh()"
|
||||
css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
allow-custom="true"
|
||||
ng-hide="ctrl.target.appInsights.dimension !== 'none'"
|
||||
model="ctrl.target.appInsights.dimension"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getAppInsightsGroupBySegments($query)"
|
||||
on-change="ctrl.refresh()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
<label class="gf-form-label min-width-20 pointer" ng-hide="ctrl.target.appInsights.dimension === 'none'"
|
||||
ng-click="ctrl.resetAppInsightsGroupBy()">{{ctrl.target.appInsights.dimension}}
|
||||
<i class="fa fa-remove"></i>
|
||||
<label
|
||||
class="gf-form-label min-width-20 pointer"
|
||||
ng-hide="ctrl.target.appInsights.dimension === 'none'"
|
||||
ng-click="ctrl.resetAppInsightsGroupBy()"
|
||||
>{{ctrl.target.appInsights.dimension}}
|
||||
<icon name="'times'"></icon>
|
||||
</label>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Filter</label>
|
||||
<input type="text" class="gf-form-input width-17" ng-model="ctrl.target.appInsights.dimensionFilter" spellcheck="false"
|
||||
placeholder="your/groupby eq 'a_value'" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-17"
|
||||
ng-model="ctrl.target.appInsights.dimensionFilter"
|
||||
spellcheck="false"
|
||||
placeholder="your/groupby eq 'a_value'"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -262,22 +372,42 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Time Grain</label>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
|
||||
<select class="gf-form-input" ng-model="ctrl.target.appInsights.timeGrainType" ng-options="f as f for f in ['auto', 'none', 'specific']"
|
||||
ng-change="ctrl.updateTimeGrainType()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.appInsights.timeGrainType"
|
||||
ng-options="f as f for f in ['auto', 'none', 'specific']"
|
||||
ng-change="ctrl.updateTimeGrainType()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-hide="ctrl.target.appInsights.timeGrainType === 'auto' || ctrl.target.appInsights.timeGrainType === 'none'">
|
||||
<input type="text" class="gf-form-input width-3" ng-model="ctrl.target.appInsights.timeGrainCount" spellcheck="false"
|
||||
placeholder="" ng-blur="ctrl.updateAppInsightsTimeGrain()">
|
||||
<div
|
||||
class="gf-form"
|
||||
ng-hide="ctrl.target.appInsights.timeGrainType === 'auto' || ctrl.target.appInsights.timeGrainType === 'none'"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-3"
|
||||
ng-model="ctrl.target.appInsights.timeGrainCount"
|
||||
spellcheck="false"
|
||||
placeholder=""
|
||||
ng-blur="ctrl.updateAppInsightsTimeGrain()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form" ng-hide="ctrl.target.appInsights.timeGrainType === 'auto' || ctrl.target.appInsights.timeGrainType === 'none'">
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent timegrainunit-dropdown-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.target.appInsights.timeGrainUnit" ng-options="f as f for f in ['minute', 'hour', 'day', 'month', 'year']"
|
||||
ng-change="ctrl.updateAppInsightsTimeGrain()"></select>
|
||||
</div>
|
||||
<div
|
||||
class="gf-form"
|
||||
ng-hide="ctrl.target.appInsights.timeGrainType === 'auto' || ctrl.target.appInsights.timeGrainType === 'none'"
|
||||
>
|
||||
<div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent timegrainunit-dropdown-wrapper">
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.appInsights.timeGrainUnit"
|
||||
ng-options="f as f for f in ['minute', 'hour', 'day', 'month', 'year']"
|
||||
ng-change="ctrl.updateAppInsightsTimeGrain()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-hide="ctrl.target.appInsights.timeGrainType !== 'auto'">
|
||||
<label class="gf-form-label">Auto Interval</label>
|
||||
<label class="gf-form-label">Auto Interval</label>
|
||||
<label class="gf-form-label">{{ctrl.getAppInsightsAutoInterval()}}</label>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -287,8 +417,14 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Legend Format</label>
|
||||
<input type="text" class="gf-form-input width-30" ng-model="ctrl.target.appInsights.alias" spellcheck="false"
|
||||
placeholder="alias patterns (see help for more info)" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-30"
|
||||
ng-model="ctrl.target.appInsights.alias"
|
||||
spellcheck="false"
|
||||
placeholder="alias patterns (see help for more info)"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -314,14 +450,25 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">X-axis</label>
|
||||
<gf-form-dropdown model="ctrl.target.appInsights.timeColumn" allow-custom="true" placeholder="eg. 'timestamp'"
|
||||
get-options="ctrl.getAppInsightsColumns($query)" on-change="ctrl.onAppInsightsColumnChange()" css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.appInsights.timeColumn"
|
||||
allow-custom="true"
|
||||
placeholder="eg. 'timestamp'"
|
||||
get-options="ctrl.getAppInsightsColumns($query)"
|
||||
on-change="ctrl.onAppInsightsColumnChange()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Y-axis</label>
|
||||
<gf-form-dropdown model="ctrl.target.appInsights.valueColumn" allow-custom="true" get-options="ctrl.getAppInsightsColumns($query)"
|
||||
on-change="ctrl.onAppInsightsColumnChange()" css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.appInsights.valueColumn"
|
||||
allow-custom="true"
|
||||
get-options="ctrl.getAppInsightsColumns($query)"
|
||||
on-change="ctrl.onAppInsightsColumnChange()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -331,8 +478,13 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-9">Split On</label>
|
||||
<gf-form-dropdown model="ctrl.target.appInsights.segmentColumn" allow-custom="true" get-options="ctrl.getAppInsightsColumns($query)"
|
||||
on-change="ctrl.onAppInsightsColumnChange()" css-class="min-width-20">
|
||||
<gf-form-dropdown
|
||||
model="ctrl.target.appInsights.segmentColumn"
|
||||
allow-custom="true"
|
||||
get-options="ctrl.getAppInsightsColumns($query)"
|
||||
on-change="ctrl.onAppInsightsColumnChange()"
|
||||
css-class="min-width-20"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
export interface FunctionDescriptor {
|
||||
text: string;
|
||||
@ -21,12 +22,13 @@ export interface FunctionEditorControlsProps {
|
||||
|
||||
const FunctionHelpButton = (props: { description: string; name: string; onDescriptionShow: () => void }) => {
|
||||
if (props.description) {
|
||||
return <span className="pointer fa fa-question-circle" onClick={props.onDescriptionShow} />;
|
||||
return <Icon className="pointer" name="question-circle" onClick={props.onDescriptionShow} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className="pointer fa fa-question-circle"
|
||||
<Icon
|
||||
className="pointer"
|
||||
name="question-circle"
|
||||
onClick={() => {
|
||||
window.open(
|
||||
'http://graphite.readthedocs.org/en/latest/functions.html#graphite.render.functions.' + props.name,
|
||||
@ -58,8 +60,8 @@ export const FunctionEditorControls = (
|
||||
description={func.def.description}
|
||||
onDescriptionShow={onDescriptionShow}
|
||||
/>
|
||||
<span className="pointer fa fa-remove" onClick={() => onRemove(func)} />
|
||||
<span className="pointer fa fa-arrow-right" onClick={() => onMoveRight(func)} />
|
||||
<Icon name="times" onClick={() => onRemove(func)} />
|
||||
<Icon name="arrow-right" onClick={() => onMoveRight(func)} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -135,7 +135,7 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">ORDER BY</label>
|
||||
<label class="gf-form-label pointer" ng-click="ctrl.removeOrderByTime()"
|
||||
>time <span class="query-keyword">DESC</span> <i class="fa fa-remove"></i
|
||||
>time <span class="query-keyword">DESC</span> <icon name="'times'"></icon
|
||||
></label>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
|
@ -70,7 +70,7 @@ export const DerivedFields = (props: Props) => {
|
||||
className={css`
|
||||
margin-right: 10px;
|
||||
`}
|
||||
icon="plus"
|
||||
icon="plus-circle"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
const newDerivedFields = [...(value || []), { name: '', matcherRegex: '' }];
|
||||
|
@ -107,7 +107,7 @@
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeFilter($index)">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</div>
|
||||
<label class="gf-form-label query-keyword" ng-hide="ctrl.addFilterMode">
|
||||
@ -154,7 +154,7 @@
|
||||
<label class="gf-form-label">
|
||||
<a ng-click="ctrl.addFilter()" ng-hide="ctrl.errors.filters">add filter</a>
|
||||
<a ng-click="ctrl.closeAddFilterMode()">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
@ -183,7 +183,7 @@
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeTag(key)">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
@ -213,7 +213,7 @@
|
||||
</label>
|
||||
<label class="gf-form-label" >
|
||||
<a ng-click="ctrl.addTag()" ng-hide="ctrl.errors.tags">add tag</a>
|
||||
<a ng-click="ctrl.closeAddTagMode()"><i class="fa fa-remove"></i></a>
|
||||
<a ng-click="ctrl.closeAddTagMode()"><icon name="'times'"></icon></a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +13,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
const removeText = '-- remove filter --';
|
||||
const removeOption: SelectableValue<string> = { label: removeText, value: removeText, icon: 'fa fa-remove' };
|
||||
const removeOption: SelectableValue<string> = { label: removeText, value: removeText, icon: 'times' };
|
||||
const operators = ['=', '!=', '=~', '!=~'];
|
||||
|
||||
export const LabelFilter: FunctionComponent<Props> = ({
|
||||
|
@ -2,6 +2,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { PanelProps } from '@grafana/data';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
@ -144,7 +145,7 @@ export class GettingStarted extends PureComponent<PanelProps, State> {
|
||||
return (
|
||||
<div className="progress-tracker-container">
|
||||
<button className="progress-tracker-close-btn" onClick={this.dismiss}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</button>
|
||||
<div className="progress-tracker">
|
||||
{this.steps.map((step, index) => {
|
||||
|
@ -1,13 +1,17 @@
|
||||
<div class="editor-row">
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">
|
||||
Type
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.mappingType"
|
||||
ng-options="f.value as f.name for f in ctrl.panel.mappingTypes" ng-change="ctrl.refresh()"></select>
|
||||
</div>
|
||||
<span class="gf-form-label">
|
||||
Type
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.mappingType"
|
||||
ng-options="f.value as f.name for f in ctrl.panel.mappingTypes"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -16,13 +20,25 @@
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form" ng-repeat="map in ctrl.panel.valueMaps">
|
||||
<span class="gf-form-label">
|
||||
<i class="fa fa-remove pointer" ng-click="ctrl.removeValueMap(map)"></i>
|
||||
<icon class="'times'" ng-click="ctrl.removeValueMap(map)"></icon>
|
||||
</span>
|
||||
<input type="text" ng-model="map.value" placeholder="value" class="gf-form-input max-width-6" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
ng-model="map.value"
|
||||
placeholder="value"
|
||||
class="gf-form-input max-width-6"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
<span class="gf-form-label">
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
<icon name="'arrow-right'"></icon>
|
||||
</span>
|
||||
<input type="text" placeholder="text" ng-model="map.text" class="gf-form-input max-width-8" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="text"
|
||||
ng-model="map.text"
|
||||
class="gf-form-input max-width-8"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
@ -37,15 +53,15 @@
|
||||
<h5 class="section-heading">Set range mappings</h5>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form" ng-repeat="rangeMap in ctrl.panel.rangeMaps">
|
||||
<span class="gf-form-label">
|
||||
<i class="fa fa-remove pointer" ng-click="ctrl.removeRangeMap(rangeMap)"></i>
|
||||
</span>
|
||||
<span class="gf-form-label">From</span>
|
||||
<input type="text" ng-model="rangeMap.from" class="gf-form-input max-width-6" ng-blur="ctrl.refresh()">
|
||||
<span class="gf-form-label">To</span>
|
||||
<input type="text" ng-model="rangeMap.to" class="gf-form-input max-width-6" ng-blur="ctrl.refresh()">
|
||||
<span class="gf-form-label">Text</span>
|
||||
<input type="text" ng-model="rangeMap.text" class="gf-form-input max-width-8" ng-blur="ctrl.refresh()">
|
||||
<span class="gf-form-label">
|
||||
<icon name="'times'" ng-click="ctrl.removeRangeMap(rangeMap)"></icon>
|
||||
</span>
|
||||
<span class="gf-form-label">From</span>
|
||||
<input type="text" ng-model="rangeMap.from" class="gf-form-input max-width-6" ng-blur="ctrl.refresh()" />
|
||||
<span class="gf-form-label">To</span>
|
||||
<input type="text" ng-model="rangeMap.to" class="gf-form-input max-width-6" ng-blur="ctrl.refresh()" />
|
||||
<span class="gf-form-label">Text</span>
|
||||
<input type="text" ng-model="rangeMap.text" class="gf-form-input max-width-8" ng-blur="ctrl.refresh()" />
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
|
@ -4,16 +4,39 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-12">Apply to columns named</label>
|
||||
<input type="text" placeholder="Name or regex" class="gf-form-input width-13" ng-model="style.pattern" bs-tooltip="'Specify regex using /my.*regex/ syntax'"
|
||||
bs-typeahead="editor.getColumnNames" ng-blur="editor.render()" data-min-length=0 data-items=100 ng-model-onblur
|
||||
data-placement="right">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Name or regex"
|
||||
class="gf-form-input width-13"
|
||||
ng-model="style.pattern"
|
||||
bs-tooltip="'Specify regex using /my.*regex/ syntax'"
|
||||
bs-typeahead="editor.getColumnNames"
|
||||
ng-blur="editor.render()"
|
||||
data-min-length="0"
|
||||
data-items="100"
|
||||
ng-model-onblur
|
||||
data-placement="right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="style.type !== 'hidden'">
|
||||
<label class="gf-form-label width-12">Column Header</label>
|
||||
<input type="text" class="gf-form-input width-12" ng-model="style.alias" ng-change="editor.render()" ng-model-onblur placeholder="Override header label">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-12"
|
||||
ng-model="style.alias"
|
||||
ng-change="editor.render()"
|
||||
ng-model-onblur
|
||||
placeholder="Override header label"
|
||||
/>
|
||||
</div>
|
||||
<gf-form-switch class="gf-form" label-class="width-12" label="Render value as link" checked="style.link" on-change="editor.render()"></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label-class="width-12"
|
||||
label="Render value as link"
|
||||
checked="style.link"
|
||||
on-change="editor.render()"
|
||||
></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="section gf-form-group">
|
||||
@ -22,37 +45,62 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Type</label>
|
||||
<div class="gf-form-select-wrapper width-16">
|
||||
<select class="gf-form-input" ng-model="style.type" ng-options="c.value as c.text for c in editor.columnTypes" ng-change="editor.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="style.type"
|
||||
ng-options="c.value as c.text for c in editor.columnTypes"
|
||||
ng-change="editor.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="style.type === 'date'">
|
||||
<label class="gf-form-label width-10">Date Format</label>
|
||||
<gf-form-dropdown model="style.dateFormat" css-class="gf-form-input width-16" lookup-text="true"
|
||||
get-options="editor.dateFormats" on-change="editor.render()" allow-custom="true">
|
||||
<gf-form-dropdown
|
||||
model="style.dateFormat"
|
||||
css-class="gf-form-input width-16"
|
||||
lookup-text="true"
|
||||
get-options="editor.dateFormats"
|
||||
on-change="editor.render()"
|
||||
allow-custom="true"
|
||||
>
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
|
||||
<div ng-if="style.type === 'string'">
|
||||
<gf-form-switch class="gf-form" label-class="width-10" ng-if="style.type === 'string'" label="Sanitize HTML" checked="style.sanitize"
|
||||
on-change="editor.render()"></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label-class="width-10"
|
||||
ng-if="style.type === 'string'"
|
||||
label="Sanitize HTML"
|
||||
checked="style.sanitize"
|
||||
on-change="editor.render()"
|
||||
></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div ng-if="style.type !== 'hidden'">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Align</label>
|
||||
<gf-form-dropdown model="style.align"
|
||||
css-class="gf-form-input width-16"
|
||||
lookup-text="true"
|
||||
get-options="editor.alignTypes"
|
||||
allow-custom="false"
|
||||
on-change="editor.render()"
|
||||
allow-custom="false"/>
|
||||
<gf-form-dropdown
|
||||
model="style.align"
|
||||
css-class="gf-form-input width-16"
|
||||
lookup-text="true"
|
||||
get-options="editor.alignTypes"
|
||||
allow-custom="false"
|
||||
on-change="editor.render()"
|
||||
allow-custom="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="style.type === 'string'">
|
||||
<gf-form-switch class="gf-form" label-class="width-10" ng-if="style.type === 'string'" label="Preserve Formatting" checked="style.preserveFormat"
|
||||
on-change="editor.render()"></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label-class="width-10"
|
||||
ng-if="style.type === 'string'"
|
||||
label="Preserve Formatting"
|
||||
checked="style.preserveFormat"
|
||||
on-change="editor.render()"
|
||||
></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div ng-if="style.type === 'number'">
|
||||
@ -62,8 +110,14 @@
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Decimals</label>
|
||||
<input type="number" class="gf-form-input width-4" data-placement="right" ng-model="style.decimals" ng-change="editor.render()"
|
||||
ng-model-onblur>
|
||||
<input
|
||||
type="number"
|
||||
class="gf-form-input width-4"
|
||||
data-placement="right"
|
||||
ng-model="style.decimals"
|
||||
ng-change="editor.render()"
|
||||
ng-model-onblur
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -77,20 +131,36 @@
|
||||
Type
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input" ng-model="style.mappingType"
|
||||
ng-options="c.value as c.text for c in editor.mappingTypes" ng-change="editor.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="style.mappingType"
|
||||
ng-options="c.value as c.text for c in editor.mappingTypes"
|
||||
ng-change="editor.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-group" ng-if="style.mappingType==1">
|
||||
<div class="gf-form" ng-repeat="map in style.valueMaps">
|
||||
<span class="gf-form-label">
|
||||
<i class="fa fa-remove pointer" ng-click="editor.removeValueMap(style, $index)"></i>
|
||||
<icon name="'times'" ng-click="editor.removeValueMap(style, $index)"></icon>
|
||||
</span>
|
||||
<input type="text" class="gf-form-input max-width-6" ng-model="map.value" placeholder="Value" ng-blur="editor.render()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input max-width-6"
|
||||
ng-model="map.value"
|
||||
placeholder="Value"
|
||||
ng-blur="editor.render()"
|
||||
/>
|
||||
<label class="gf-form-label">
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
<icon name="'arrow-right'"></icon>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input max-width-8" ng-model="map.text" placeholder="Text" ng-blur="editor.render()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input max-width-8"
|
||||
ng-model="map.text"
|
||||
placeholder="Text"
|
||||
ng-blur="editor.render()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
@ -101,18 +171,18 @@
|
||||
<div class="gf-form-group" ng-if="style.mappingType==2">
|
||||
<div class="gf-form" ng-repeat="rangeMap in style.rangeMaps">
|
||||
<span class="gf-form-label">
|
||||
<i class="fa fa-remove pointer" ng-click="editor.removeRangeMap(style, $index)"></i>
|
||||
<icon name="'times'" ng-click="editor.removeRangeMap(style, $index)"></icon>
|
||||
</span>
|
||||
<span class="gf-form-label">From</span>
|
||||
<input type="text" ng-model="rangeMap.from" class="gf-form-input max-width-6" ng-blur="editor.render()">
|
||||
<input type="text" ng-model="rangeMap.from" class="gf-form-input max-width-6" ng-blur="editor.render()" />
|
||||
<span class="gf-form-label">To</span>
|
||||
<input type="text" ng-model="rangeMap.to" class="gf-form-input max-width-6" ng-blur="editor.render()">
|
||||
<input type="text" ng-model="rangeMap.to" class="gf-form-input max-width-6" ng-blur="editor.render()" />
|
||||
<span class="gf-form-label">Text</span>
|
||||
<input type="text" ng-model="rangeMap.text" class="gf-form-input max-width-8" ng-blur="editor.render()">
|
||||
<input type="text" ng-model="rangeMap.text" class="gf-form-input max-width-8" ng-blur="editor.render()" />
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" ng-click="editor.addRangeMap(style)"><i class="fa fa-plus"></i></a>
|
||||
<a class="pointer" ng-click="editor.addRangeMap(style)"><icon name="'plus-circle'"></icon></a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -123,16 +193,28 @@
|
||||
<div class="section gf-form-group" ng-if="['number', 'string'].indexOf(style.type) !== -1">
|
||||
<h5 class="section-heading">Thresholds</h5>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-8">Thresholds
|
||||
<label class="gf-form-label width-8"
|
||||
>Thresholds
|
||||
<tip>Comma separated values</tip>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input width-10" ng-model="style.thresholds" placeholder="50,80" ng-blur="editor.render()"
|
||||
array-join>
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-10"
|
||||
ng-model="style.thresholds"
|
||||
placeholder="50,80"
|
||||
ng-blur="editor.render()"
|
||||
array-join
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-8">Color Mode</label>
|
||||
<div class="gf-form-select-wrapper width-10">
|
||||
<select class="gf-form-input" ng-model="style.colorMode" ng-options="c.value as c.text for c in editor.colorModes" ng-change="editor.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="style.colorMode"
|
||||
ng-options="c.value as c.text for c in editor.colorModes"
|
||||
ng-change="editor.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
@ -161,17 +243,25 @@
|
||||
<p>Specify an URL (relative or absolute)</p>
|
||||
<span>
|
||||
Use special variables to specify cell values:
|
||||
<br>
|
||||
<br />
|
||||
<em>${__cell}</em> refers to current cell value
|
||||
<br>
|
||||
<em>${__cell_n}</em> refers to Nth column value in current row. Column indexes are started from 0. For instance,
|
||||
<em>${__cell_1}</em> refers to second column's value.
|
||||
<br>
|
||||
<em>${__cell:raw}</em> disables all encoding. Useful if the value is a complete URL. By default values are URI encoded.
|
||||
<br />
|
||||
<em>${__cell_n}</em> refers to Nth column value in current row. Column indexes are started from 0. For
|
||||
instance, <em>${__cell_1}</em> refers to second column's value.
|
||||
<br />
|
||||
<em>${__cell:raw}</em> disables all encoding. Useful if the value is a complete URL. By default values are
|
||||
URI encoded.
|
||||
</span>
|
||||
</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input width-29" ng-model="style.linkUrl" ng-blur="editor.render()" ng-model-onblur data-placement="right">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-29"
|
||||
ng-model="style.linkUrl"
|
||||
ng-blur="editor.render()"
|
||||
ng-model-onblur
|
||||
data-placement="right"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-9">
|
||||
@ -179,14 +269,25 @@
|
||||
<info-popover mode="right-normal">
|
||||
<p>Specify text for link tooltip.</p>
|
||||
<span>
|
||||
This title appears when user hovers pointer over the cell with link. Use the same variables as for URL.
|
||||
This title appears when user hovers pointer over the cell with link. Use the same variables as for URL.
|
||||
</span>
|
||||
</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input width-29" ng-model="style.linkTooltip" ng-blur="editor.render()" ng-model-onblur
|
||||
data-placement="right">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-29"
|
||||
ng-model="style.linkTooltip"
|
||||
ng-blur="editor.render()"
|
||||
ng-model-onblur
|
||||
data-placement="right"
|
||||
/>
|
||||
</div>
|
||||
<gf-form-switch class="gf-form" label-class="width-9" label="Open in new tab" checked="style.linkTargetBlank"></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label-class="width-9"
|
||||
label="Open in new tab"
|
||||
checked="style.linkTargetBlank"
|
||||
></gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
@ -196,7 +297,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
@ -204,4 +305,3 @@
|
||||
<i class="fa fa-plus"></i> Add column style
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<div class="gf-form" ng-repeat="column in editor.panel.columns">
|
||||
<label class="gf-form-label">
|
||||
<i class="pointer fa fa-remove" ng-click="editor.removeColumn(column)"></i>
|
||||
<icon name="'times'" ng-click="editor.removeColumn(column)"></icon>
|
||||
<span>{{ column.text }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -40,8 +40,7 @@ $input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form-input-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
top: 10px;
|
||||
font-size: $font-size-lg;
|
||||
left: 10px;
|
||||
color: $input-color-placeholder;
|
||||
@ -370,7 +369,6 @@ $input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form-help-icon {
|
||||
flex-grow: 0;
|
||||
padding-left: $spacer;
|
||||
color: $text-color-weak;
|
||||
|
||||
&--bold {
|
||||
|
@ -101,6 +101,7 @@
|
||||
|
||||
.alert-rule-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $card-background;
|
||||
|
@ -23,15 +23,6 @@ angular.module('grafana.routes', ['ngRoute']);
|
||||
jest.mock('app/core/core', () => ({}));
|
||||
jest.mock('app/features/plugins/plugin_loader', () => ({}));
|
||||
|
||||
/* Temporary solution as Jest can't parse Unicons imports.
|
||||
* Therefore we are mocking in for all tests. Needs to be fixed before merging to master.
|
||||
*/
|
||||
jest.mock('@grafana/ui/src/components/Icon/Icon', () => {
|
||||
return {
|
||||
Icon: () => null as any,
|
||||
};
|
||||
});
|
||||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
const localStorageMock = (() => {
|
||||
|
Loading…
Reference in New Issue
Block a user