Part2: Unicons implementation (#23266)
* 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> * Icons update * Add optional chaining to for isFontAwesome variable Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
co-authored by
Torkel Ödegaard
parent
2d48bb8921
commit
d2d61d9bc2
@@ -2,6 +2,7 @@ import React, { AnchorHTMLAttributes, ButtonHTMLAttributes, useContext } from 'r
|
||||
import { css, cx } from 'emotion';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { selectThemeVariant, stylesFactory, ThemeContext } from '../../themes';
|
||||
import { IconName } from '../../types';
|
||||
import { getFocusStyle, getPropertiesForButtonSize } from '../Forms/commonStyles';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { ButtonContent } from './ButtonContent';
|
||||
@@ -134,7 +135,7 @@ export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link';
|
||||
type CommonProps = {
|
||||
size?: ComponentSize;
|
||||
variant?: ButtonVariant;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
@@ -151,7 +152,9 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
|
||||
return (
|
||||
<button className={cx(styles.button, className)} {...otherProps} ref={ref}>
|
||||
<ButtonContent icon={icon}>{children}</ButtonContent>
|
||||
<ButtonContent icon={icon} size={otherProps.size}>
|
||||
{children}
|
||||
</ButtonContent>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -171,7 +174,9 @@ export const LinkButton = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
|
||||
|
||||
return (
|
||||
<a className={cx(styles.button, className)} {...otherProps} ref={ref}>
|
||||
<ButtonContent icon={icon}>{children}</ButtonContent>
|
||||
<ButtonContent icon={icon} size={otherProps.size}>
|
||||
{children}
|
||||
</ButtonContent>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { css } from 'emotion';
|
||||
import { stylesFactory, useTheme } from '../../themes';
|
||||
import { IconName } from '../../types';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { ComponentSize } from '../../types/size';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
|
||||
@@ -14,8 +16,6 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
`,
|
||||
|
||||
icon: css`
|
||||
position: relative;
|
||||
top: 1px;
|
||||
& + * {
|
||||
margin-left: ${theme.spacing.sm};
|
||||
}
|
||||
@@ -23,28 +23,24 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
size?: ComponentSize;
|
||||
};
|
||||
|
||||
export function ButtonContent(props: Props) {
|
||||
const { icon, children } = props;
|
||||
const { icon, children, size } = props;
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme);
|
||||
|
||||
if (!children) {
|
||||
return (
|
||||
<span className={styles.content}>
|
||||
<i className={icon} />
|
||||
</span>
|
||||
);
|
||||
return <span className={styles.content}>{icon && <Icon name={icon} size={size} />}</span>;
|
||||
}
|
||||
|
||||
const iconElement = icon && (
|
||||
<span className={styles.icon}>
|
||||
<i className={icon} />
|
||||
<Icon name={icon} size={size} />
|
||||
</span>
|
||||
);
|
||||
|
||||
|
||||
@@ -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="fa fa-plus" onClick={action('cta button clicked')}>
|
||||
<Button size="lg" icon="plus" onClick={action('cta button clicked')}>
|
||||
Add datasource
|
||||
</Button>
|
||||
),
|
||||
|
||||
@@ -65,7 +65,7 @@ storiesOf('General/ConfirmButton', module)
|
||||
action('Saved')('save!');
|
||||
}}
|
||||
>
|
||||
<Button size={size} variant="secondary" icon="fa fa-pencil">
|
||||
<Button size={size} variant="secondary" icon="pen">
|
||||
{buttonText}
|
||||
</Button>
|
||||
</ConfirmButton>
|
||||
|
||||
@@ -18,7 +18,7 @@ export const DeleteButton: FC<Props> = ({ size, disabled, onConfirm }) => {
|
||||
disabled={disabled}
|
||||
onConfirm={onConfirm}
|
||||
>
|
||||
<Button variant="destructive" icon="fa fa-remove" size={size || 'sm'} />
|
||||
<Button variant="destructive" icon="times" size={size || 'sm'} />
|
||||
</ConfirmButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ export const DataLinksEditor: FC<DataLinksEditorProps> = React.memo(
|
||||
)}
|
||||
|
||||
{(!value || (value && value.length < (maxLinks || Infinity))) && (
|
||||
<Button variant="secondary" icon="fa fa-plus" onClick={() => onAdd()}>
|
||||
<Button variant="secondary" icon="plus" onClick={() => onAdd()}>
|
||||
Add link
|
||||
</Button>
|
||||
)}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ export const DataLinksInlineEditor: React.FC<DataLinksInlineEditorProps> = ({ li
|
||||
)}
|
||||
|
||||
<FullWidthButtonContainer>
|
||||
<Button size="sm" icon="fa fa-plus" onClick={onDataLinkAdd} variant="secondary">
|
||||
<Button size="sm" icon="plus" onClick={onDataLinkAdd} variant="secondary">
|
||||
Add link
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { FunctionComponent, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Tooltip, PopoverContent } from '../Tooltip/Tooltip';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
@@ -33,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">
|
||||
<i className="fa fa-info-circle" />
|
||||
<Icon name="info-circle" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -135,26 +135,12 @@ $select-input-bg-disabled: $input-bg-disabled;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
right: 8px;
|
||||
top: 1px;
|
||||
margin-top: -1px;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gf-form-select-box__select-arrow {
|
||||
border-color: $input-color-select-arrow transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 4px 4px 2.5px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 2px;
|
||||
margin-top: -2px;
|
||||
|
||||
&.gf-form-select-box__select-arrow--reversed {
|
||||
border-color: transparent transparent $input-color-select-arrow;
|
||||
border-width: 0 4px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-input--form-dropdown {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
|
||||
@@ -43,6 +43,13 @@ export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
|
||||
const theme = useTheme();
|
||||
const styles = getIconStyles(theme, type);
|
||||
const svgSize = getSvgSize(size, theme);
|
||||
|
||||
/* Temporary solution to display also font awesome icons */
|
||||
const isFontAwesome = name?.includes('fa-');
|
||||
if (isFontAwesome) {
|
||||
return <i className={cx(name, className)} {...divElementProps} style={style} />;
|
||||
}
|
||||
|
||||
const iconName = type === 'default' ? `Uil${toPascalCase(name)}` : toPascalCase(name);
|
||||
|
||||
/* Unicons don't have type definitions */
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const Bell: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
{...rest}
|
||||
>
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M18,13.18463V10c0-3.31372-2.68628-6-6-6s-6,2.68628-6,6v3.18463C4.83832,13.59863,4.00146,14.69641,4,16v2c0,0.00037,0,0.00073,0,0.00116C4.00031,18.5531,4.44806,19.00031,5,19h14c0.00037,0,0.00073,0,0.00116,0C19.5531,18.99969,20.00031,18.55194,20,18v-2C19.99854,14.69641,19.16168,13.59863,18,13.18463z"
|
||||
/>
|
||||
<path d="M8.14233 19c.4472 1.72119 1.99689 2.99817 3.85767 3 1.86078-.00183 3.41046-1.27881 3.85767-3H8.14233zM12 4c.34149 0 .67413.03516 1 .08997V3c0-.55231-.44769-1-1-1s-1 .44769-1 1v1.08997C11.32587 4.03516 11.65851 4 12 4z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const Favorite: FunctionComponent<SvgProps> = ({ size, color, secondaryColor, ...rest }) => {
|
||||
export const Favorite: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width={size} height={size} {...rest}>
|
||||
<path d="M17.56249,21.55957a.99941.99941,0,0,1-.46581-.11523L12,18.76465,6.90332,21.44434a.9999.9999,0,0,1-1.45117-1.05372l.97363-5.67578-4.124-4.01953a.99965.99965,0,0,1,.55469-1.70508l5.69824-.82812,2.54883-5.16406a1.04012,1.04012,0,0,1,1.793,0l2.54883,5.16406,5.69824.82812a.99965.99965,0,0,1,.55469,1.70508l-4.124,4.01953.97363,5.67578a1.00024,1.00024,0,0,1-.98536,1.169Z" />
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const Folder: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width={size} height={size} {...rest}>
|
||||
<path d="M19,21.5H5a3.00328,3.00328,0,0,1-3-3V5.5a3.00328,3.00328,0,0,1,3-3H9.55859A2.99629,2.99629,0,0,1,12.4043,4.55078L12.7207,5.5H19a3.00328,3.00328,0,0,1,3,3v10A3.00328,3.00328,0,0,1,19,21.5Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const FolderPlus: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
{...rest}
|
||||
>
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M19,21.5H5a3.00328,3.00328,0,0,1-3-3V5.5a3.00328,3.00328,0,0,1,3-3H9.55859A2.99629,2.99629,0,0,1,12.4043,4.55078L12.7207,5.5H19a3.00328,3.00328,0,0,1,3,3v10A3.00328,3.00328,0,0,1,19,21.5Z"
|
||||
/>
|
||||
<path d="M14,12.5H13v-1a1,1,0,0,0-2,0v1H10a1,1,0,0,0,0,2h1v1a1,1,0,0,0,2,0v-1h1a1,1,0,0,0,0-2Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const Grafana: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 85.12 92.46" height={size} width={size} {...rest}>
|
||||
<defs>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="42.562" y1="113.2595" x2="42.562" y2="28.7828">
|
||||
<stop offset="0" style={{ stopColor: '#FFF200' }} />
|
||||
<stop offset="1" style={{ stopColor: '#F15A29' }} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#SVGID_1_)"
|
||||
d="M85.01,40.8c-0.14-1.55-0.41-3.35-0.93-5.32c-0.51-1.97-1.28-4.13-2.39-6.37c-1.12-2.24-2.57-4.57-4.47-6.82
|
||||
c-0.74-0.88-1.54-1.76-2.42-2.6c1.3-5.17-1.59-9.65-1.59-9.65c-4.98-0.31-8.14,1.54-9.31,2.39c-0.2-0.08-0.39-0.17-0.59-0.25
|
||||
c-0.85-0.34-1.72-0.66-2.61-0.95c-0.89-0.28-1.81-0.54-2.74-0.76c-0.94-0.22-1.89-0.4-2.86-0.55c-0.17-0.03-0.34-0.05-0.51-0.07
|
||||
C52.41,2.9,46.18,0,46.18,0c-6.95,4.41-8.27,10.57-8.27,10.57s-0.03,0.14-0.07,0.36c-0.38,0.11-0.77,0.22-1.15,0.34
|
||||
c-0.53,0.16-1.06,0.36-1.59,0.55c-0.53,0.21-1.06,0.41-1.58,0.64c-1.05,0.45-2.09,0.96-3.1,1.53c-0.99,0.55-1.95,1.16-2.9,1.82
|
||||
c-0.14-0.06-0.24-0.11-0.24-0.11c-9.62-3.68-18.17,0.75-18.17,0.75c-0.78,10.24,3.84,16.68,4.76,17.86
|
||||
c-0.23,0.63-0.44,1.27-0.64,1.92c-0.71,2.32-1.24,4.7-1.57,7.16c-0.05,0.35-0.09,0.71-0.13,1.07C2.63,48.84,0,57.84,0,57.84
|
||||
c7.42,8.53,16.07,9.06,16.07,9.06c0.01-0.01,0.02-0.01,0.02-0.02c1.1,1.96,2.37,3.83,3.8,5.57c0.6,0.73,1.23,1.43,1.88,2.11
|
||||
c-2.71,7.74,0.38,14.18,0.38,14.18c8.26,0.31,13.69-3.61,14.83-4.52c0.82,0.28,1.66,0.53,2.5,0.74c2.54,0.65,5.14,1.04,7.74,1.15
|
||||
c0.65,0.03,1.3,0.04,1.95,0.04l0.31,0l0.21-0.01l0.41-0.01l0.4-0.02l0.01,0.01c3.89,5.55,10.74,6.34,10.74,6.34
|
||||
c4.87-5.13,5.15-10.22,5.15-11.33l0,0c0,0,0-0.04,0-0.07c0-0.09,0-0.15,0-0.15s0,0,0,0c0-0.08-0.01-0.15-0.01-0.23
|
||||
c1.02-0.72,2-1.49,2.92-2.31c1.95-1.76,3.65-3.77,5.06-5.93c0.13-0.2,0.26-0.41,0.39-0.62c5.51,0.32,9.39-3.41,9.39-3.41
|
||||
c-0.91-5.74-4.18-8.54-4.87-9.07l0,0c0,0-0.03-0.02-0.07-0.05c-0.04-0.03-0.06-0.05-0.06-0.05l0,0c-0.04-0.02-0.08-0.05-0.12-0.08
|
||||
c0.03-0.35,0.06-0.69,0.08-1.04c0.04-0.62,0.06-1.24,0.06-1.85l0-0.46l0-0.23l0-0.12c0-0.16,0-0.1,0-0.16l-0.02-0.38l-0.03-0.52
|
||||
c-0.01-0.18-0.02-0.34-0.04-0.5c-0.01-0.16-0.03-0.32-0.05-0.48l-0.06-0.48l-0.07-0.47c-0.09-0.63-0.21-1.26-0.36-1.88
|
||||
c-0.58-2.47-1.54-4.82-2.82-6.93c-1.28-2.11-2.86-3.98-4.65-5.56c-1.79-1.58-3.79-2.85-5.9-3.79c-2.1-0.95-4.31-1.55-6.51-1.83
|
||||
c-1.1-0.14-2.2-0.2-3.28-0.19l-0.41,0.01l-0.1,0c-0.03,0-0.15,0-0.14,0l-0.17,0.01l-0.4,0.03c-0.15,0.01-0.31,0.02-0.45,0.04
|
||||
c-0.56,0.05-1.11,0.13-1.66,0.23c-2.18,0.41-4.24,1.2-6.06,2.28c-1.82,1.09-3.39,2.45-4.68,3.98c-1.28,1.54-2.28,3.24-2.96,5
|
||||
c-0.69,1.76-1.07,3.58-1.18,5.35c-0.03,0.44-0.04,0.88-0.03,1.32c0,0.11,0,0.22,0.01,0.33l0.01,0.35c0.02,0.21,0.03,0.42,0.05,0.63
|
||||
c0.09,0.9,0.25,1.75,0.49,2.58c0.48,1.66,1.25,3.15,2.2,4.43c0.95,1.28,2.08,2.33,3.28,3.15c1.2,0.82,2.49,1.41,3.76,1.79
|
||||
c1.27,0.38,2.54,0.54,3.74,0.53c0.15,0,0.3,0,0.44-0.01c0.08,0,0.16-0.01,0.24-0.01c0.08,0,0.16-0.01,0.24-0.01
|
||||
c0.13-0.01,0.25-0.03,0.38-0.04c0.03,0,0.07-0.01,0.11-0.01l0.12-0.02c0.08-0.01,0.15-0.02,0.23-0.03c0.16-0.02,0.29-0.05,0.43-0.08
|
||||
c0.14-0.03,0.28-0.05,0.42-0.09c0.27-0.06,0.54-0.14,0.8-0.22c0.52-0.17,1.01-0.38,1.46-0.61c0.45-0.23,0.87-0.5,1.26-0.77
|
||||
c0.11-0.08,0.22-0.16,0.33-0.25c0.42-0.33,0.48-0.94,0.15-1.35c-0.29-0.36-0.79-0.45-1.19-0.23c-0.1,0.05-0.2,0.11-0.3,0.16
|
||||
c-0.35,0.17-0.71,0.32-1.09,0.45c-0.39,0.12-0.79,0.22-1.2,0.29c-0.21,0.03-0.42,0.06-0.63,0.08c-0.11,0.01-0.21,0.02-0.32,0.02
|
||||
c-0.11,0-0.22,0.01-0.32,0.01c-0.1,0-0.21,0-0.31-0.01c-0.13-0.01-0.26-0.01-0.39-0.02c0,0-0.07,0-0.01,0l-0.04,0L51.4,61.6
|
||||
c-0.06-0.01-0.12-0.01-0.17-0.02c-0.12-0.01-0.23-0.03-0.35-0.04c-0.93-0.13-1.88-0.4-2.79-0.82c-0.91-0.41-1.79-0.98-2.57-1.69
|
||||
c-0.79-0.71-1.48-1.56-2.01-2.52c-0.54-0.96-0.92-2.03-1.09-3.16c-0.09-0.56-0.13-1.14-0.11-1.71c0.01-0.16,0.01-0.31,0.02-0.47
|
||||
c0,0.04,0-0.02,0-0.03l0-0.06l0.01-0.12c0.01-0.08,0.01-0.15,0.02-0.23c0.03-0.31,0.08-0.62,0.13-0.92
|
||||
c0.43-2.45,1.65-4.83,3.55-6.65c0.47-0.45,0.98-0.87,1.53-1.25c0.55-0.37,1.12-0.7,1.73-0.98c0.6-0.28,1.23-0.5,1.88-0.68
|
||||
c0.65-0.17,1.31-0.29,1.98-0.35c0.34-0.03,0.67-0.04,1.01-0.04c0.09,0,0.16,0,0.23,0l0.27,0.01l0.17,0.01c0.07,0,0,0,0.03,0l0.07,0
|
||||
l0.27,0.02c0.73,0.06,1.46,0.16,2.17,0.32c1.43,0.32,2.83,0.85,4.13,1.57c2.6,1.44,4.81,3.69,6.17,6.4c0.69,1.35,1.16,2.81,1.4,4.31
|
||||
c0.06,0.38,0.1,0.76,0.13,1.14l0.02,0.29l0.01,0.29c0.01,0.1,0.01,0.19,0.01,0.29c0,0.09,0.01,0.2,0,0.27l0,0.25l-0.01,0.28
|
||||
c-0.01,0.19-0.02,0.49-0.03,0.67c-0.03,0.42-0.07,0.83-0.12,1.24c-0.05,0.41-0.12,0.82-0.19,1.22c-0.08,0.4-0.17,0.81-0.27,1.21
|
||||
c-0.2,0.8-0.46,1.59-0.76,2.36c-0.61,1.54-1.42,3-2.4,4.36c-1.96,2.7-4.64,4.9-7.69,6.29c-1.52,0.69-3.13,1.19-4.78,1.47
|
||||
c-0.82,0.14-1.66,0.22-2.5,0.25l-0.15,0.01l-0.13,0l-0.27,0l-0.41,0l-0.21,0c0.11,0-0.02,0-0.01,0l-0.08,0
|
||||
c-0.45-0.01-0.9-0.03-1.34-0.07c-1.79-0.13-3.55-0.45-5.27-0.95c-1.71-0.49-3.38-1.16-4.95-2c-3.14-1.68-5.95-3.98-8.15-6.76
|
||||
c-1.11-1.38-2.07-2.87-2.87-4.43c-0.8-1.56-1.42-3.2-1.89-4.88c-0.46-1.68-0.75-3.39-0.86-5.12l-0.02-0.32l-0.01-0.08l0-0.07l0-0.14
|
||||
l-0.01-0.28l0-0.07l0-0.1l0-0.2l-0.01-0.4l0-0.08c0,0.01,0,0.01,0-0.03l0-0.16c0-0.21,0.01-0.42,0.01-0.63
|
||||
c0.03-0.85,0.1-1.73,0.21-2.61c0.11-0.88,0.26-1.76,0.44-2.63c0.18-0.87,0.39-1.74,0.64-2.59c0.49-1.71,1.1-3.36,1.82-4.92
|
||||
c1.44-3.12,3.34-5.88,5.61-8.09c0.57-0.55,1.16-1.08,1.77-1.57c0.61-0.49,1.25-0.95,1.9-1.37c0.65-0.43,1.32-0.82,2.02-1.18
|
||||
c0.34-0.19,0.7-0.35,1.05-0.52c0.18-0.08,0.36-0.16,0.53-0.24c0.18-0.08,0.36-0.16,0.54-0.23c0.72-0.3,1.46-0.56,2.21-0.8
|
||||
c0.19-0.06,0.38-0.11,0.56-0.17c0.19-0.06,0.38-0.1,0.57-0.16c0.38-0.11,0.76-0.2,1.14-0.29c0.19-0.05,0.39-0.08,0.58-0.13
|
||||
c0.19-0.04,0.38-0.08,0.58-0.12c0.19-0.04,0.39-0.07,0.58-0.11l0.29-0.05l0.29-0.04c0.2-0.03,0.39-0.06,0.59-0.09
|
||||
c0.22-0.04,0.44-0.05,0.66-0.09c0.18-0.02,0.48-0.06,0.65-0.08c0.14-0.01,0.28-0.03,0.41-0.04l0.28-0.03l0.14-0.01l0.16-0.01
|
||||
c0.22-0.01,0.44-0.03,0.66-0.04l0.33-0.02c0,0,0.12,0,0.02,0l0.07,0l0.14-0.01c0.19-0.01,0.38-0.02,0.56-0.03
|
||||
c0.75-0.02,1.5-0.02,2.24,0c1.48,0.06,2.93,0.22,4.34,0.48c2.82,0.53,5.49,1.43,7.89,2.62c2.41,1.18,4.57,2.63,6.44,4.2
|
||||
c0.12,0.1,0.23,0.2,0.35,0.3c0.11,0.1,0.23,0.2,0.34,0.3c0.23,0.2,0.44,0.41,0.66,0.61c0.22,0.2,0.43,0.41,0.64,0.62
|
||||
c0.2,0.21,0.41,0.41,0.61,0.63c0.8,0.84,1.53,1.69,2.19,2.55c1.33,1.71,2.39,3.44,3.24,5.07c0.05,0.1,0.11,0.2,0.16,0.3
|
||||
c0.05,0.1,0.1,0.2,0.15,0.3c0.1,0.2,0.2,0.4,0.29,0.6c0.09,0.2,0.19,0.39,0.27,0.59c0.09,0.2,0.17,0.39,0.25,0.58
|
||||
c0.32,0.76,0.61,1.49,0.84,2.18c0.39,1.11,0.67,2.11,0.89,2.98c0.09,0.35,0.42,0.58,0.78,0.55c0.37-0.03,0.66-0.34,0.66-0.71
|
||||
C85.14,43.15,85.11,42.05,85.01,40.8z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const Import: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
{...rest}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24">
|
||||
<path d="M19,22H5c-1.65611-0.00181-2.99819-1.34389-3-3v-4c0-0.55229,0.44772-1,1-1s1,0.44771,1,1v4c0.00037,0.55213,0.44787,0.99963,1,1h14c0.55213-0.00037,0.99963-0.44787,1-1v-4c0-0.55229,0.44772-1,1-1s1,0.44771,1,1v4C21.99819,20.65611,20.65611,21.99819,19,22z" />
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M16.707,10.293c-0.39027-0.39048-1.02319-0.39065-1.41368-0.00038c-0.00013,0.00013-0.00026,0.00026-0.00038,0.00038L13,12.58594V3c0-0.55228-0.44771-1-1-1s-1,0.44772-1,1v9.58594L8.707,10.293c-0.39402-0.38691-1.02709-0.38116-1.414,0.01286c-0.38195,0.38896-0.38195,1.01218,0,1.40114l4,4c0.39028,0.39048,1.02321,0.39065,1.41369,0.00037c0.00012-0.00012,0.00025-0.00025,0.00037-0.00037l4-4c0.39045-0.3903,0.39058-1.02322,0.00028-1.41367C16.70723,10.29322,16.70712,10.29311,16.707,10.293z"
|
||||
/>
|
||||
</svg>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { SvgProps } from '../Icon';
|
||||
|
||||
export const PlusSquare: FunctionComponent<SvgProps> = ({ size, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
{...rest}
|
||||
>
|
||||
<path d="M17,11H13V7a1,1,0,0,0-2,0v4H7a1,1,0,0,0,0,2h4v4a1,1,0,0,0,2,0V13h4a1,1,0,0,0,0-2Z" />
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M21,2H3A.99974.99974,0,0,0,2,3V21a.99974.99974,0,0,0,1,1H21a.99974.99974,0,0,0,1-1V3A.99974.99974,0,0,0,21,2ZM17,13H13v4a1,1,0,0,1-2,0V13H7a1,1,0,0,1,0-2h4V7a1,1,0,0,1,2,0v4h4a1,1,0,0,1,0,2Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -2,3 +2,9 @@ export * from './Apps';
|
||||
export * from './Cog';
|
||||
export * from './Shield';
|
||||
export * from './Favorite';
|
||||
export * from './Grafana';
|
||||
export * from './Bell';
|
||||
export * from './PlusSquare';
|
||||
export * from './FolderPlus';
|
||||
export * from './Folder';
|
||||
export * from './Import';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Tooltip, TooltipProps, PopoverContent } from '../Tooltip/Tooltip';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
interface InfoTooltipProps extends Omit<TooltipProps, 'children' | 'content'> {
|
||||
children: PopoverContent;
|
||||
@@ -8,7 +9,7 @@ interface InfoTooltipProps extends Omit<TooltipProps, 'children' | 'content'> {
|
||||
export const InfoTooltip = ({ children, ...restProps }: InfoTooltipProps) => {
|
||||
return (
|
||||
<Tooltip content={children} {...restProps}>
|
||||
<i className="fa fa-info-circle" />
|
||||
<Icon name="info-circle" />
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -129,7 +129,7 @@ class UnThemedLogDetailsRow extends PureComponent<Props, State> {
|
||||
<LinkButton
|
||||
variant="link"
|
||||
size={'sm'}
|
||||
icon={cx('fa', link.onClick ? 'fa-list' : 'fa-external-link')}
|
||||
icon={link.onClick ? 'list-ul' : 'external-link-alt'}
|
||||
href={link.href}
|
||||
target={'_blank'}
|
||||
onClick={
|
||||
|
||||
@@ -16,7 +16,7 @@ export const ModalHeader: React.FC<Props> = ({ icon, title, children }) => {
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.modalHeaderTitle}>
|
||||
{icon && <Icon name={icon} className={styles.modalHeaderIcon} />}
|
||||
{icon && <Icon name={icon} size="lg" className={styles.modalHeaderIcon} />}
|
||||
{title}
|
||||
</h2>
|
||||
{children}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { cx } from 'emotion';
|
||||
import { IconName } from '../../types';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
@@ -8,19 +9,10 @@ interface Props {
|
||||
}
|
||||
|
||||
export const ModalTabContent: React.FC<Props> = ({ icon, iconClass, children }) => {
|
||||
let iconElem;
|
||||
const showIcon = icon || iconClass;
|
||||
if (iconClass) {
|
||||
iconElem = <i className={iconClass}></i>;
|
||||
}
|
||||
if (icon) {
|
||||
iconElem = <Icon name={icon} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
{showIcon && <div className="share-modal-big-icon">{iconElem}</div>}
|
||||
{icon && <Icon name={icon} size="xxl" className={cx(iconClass, 'share-modal-big-icon')} />}
|
||||
<div className="share-modal-content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ModalHeader } from './ModalHeader';
|
||||
interface ModalTab {
|
||||
value: string;
|
||||
label: string;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import * as PopperJS from 'popper.js';
|
||||
|
||||
export interface Props {
|
||||
@@ -54,7 +55,7 @@ export class Switch extends PureComponent<Props, State> {
|
||||
{tooltip && (
|
||||
<Tooltip placement={tooltipPlacement ? tooltipPlacement : 'auto'} content={tooltip} theme={'info'}>
|
||||
<div className="gf-form-help-icon gf-form-help-icon--right-normal">
|
||||
<i className="fa fa-info-circle" />
|
||||
<Icon name="info-circle" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { FC } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconName } from '../../types';
|
||||
import { stylesFactory, useTheme } from '../../themes';
|
||||
|
||||
export interface TabProps {
|
||||
label: string;
|
||||
active?: boolean;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
onChangeTab: () => void;
|
||||
}
|
||||
|
||||
@@ -26,15 +28,10 @@ const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
color: ${colors.text};
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
svg {
|
||||
margin-right: ${theme.spacing.sm};
|
||||
}
|
||||
|
||||
.gicon {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: ${colors.linkHover};
|
||||
@@ -67,7 +64,7 @@ export const Tab: FC<TabProps> = ({ label, active, icon, onChangeTab }) => {
|
||||
|
||||
return (
|
||||
<li className={cx(tabsStyles.tabItem, active && tabsStyles.activeStyle)} onClick={onChangeTab}>
|
||||
{icon && <i className={icon} />}
|
||||
{icon && <Icon name={icon} />}
|
||||
{label}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -200,7 +200,7 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<FullWidthButtonContainer className={styles.addButton}>
|
||||
<Button size="sm" icon="fa fa-plus" onClick={() => this.onAddThreshold()} variant="secondary">
|
||||
<Button size="sm" icon="plus" onClick={() => this.onAddThreshold()} variant="secondary">
|
||||
Add threshold
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ const getBodyStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
|
||||
return {
|
||||
title: css`
|
||||
color: ${theme.colors.text}
|
||||
color: ${theme.colors.text};
|
||||
background-color: ${colors.background};
|
||||
font-size: ${theme.typography.size.md};
|
||||
border: 1px solid transparent;
|
||||
|
||||
@@ -62,7 +62,7 @@ export const TimeRangeForm: React.FC<Props> = props => {
|
||||
[timeZone]
|
||||
);
|
||||
|
||||
const icon = isFullscreen ? null : <Button icon="fa fa-calendar" variant="secondary" onClick={onOpen} />;
|
||||
const icon = isFullscreen ? null : <Button icon="calendar-alt" variant="secondary" onClick={onOpen} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -118,7 +118,7 @@ export class TransformationsEditor extends React.PureComponent<TransformationsEd
|
||||
return (
|
||||
<>
|
||||
{this.renderTransformationEditors()}
|
||||
<Button variant="secondary" icon="fa fa-plus" onClick={this.onTransformationAdd}>
|
||||
<Button variant="secondary" icon="plus" onClick={this.onTransformationAdd}>
|
||||
Add transformation
|
||||
</Button>
|
||||
</>
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ export class LegacyValueMappingsEditor extends PureComponent<Props, State> {
|
||||
removeValueMapping={() => this.onRemoveMapping(valueMapping.id)}
|
||||
/>
|
||||
))}
|
||||
<Button variant="primary" icon="fa fa-plus" onClick={this.onAddMapping}>
|
||||
<Button variant="primary" icon="plus" onClick={this.onAddMapping}>
|
||||
Add mapping
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@ export const ValueMappingsEditor: React.FC<Props> = ({ valueMappings, onChange,
|
||||
<FullWidthButtonContainer>
|
||||
<Button
|
||||
size="sm"
|
||||
icon="fa fa-plus"
|
||||
icon="plus"
|
||||
onClick={onAdd}
|
||||
aria-label="ValueMappingsEditor add mapping button"
|
||||
variant="secondary"
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ exports[`Render should render component 1`] = `
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
icon="fa fa-plus"
|
||||
icon="plus"
|
||||
onClick={[Function]}
|
||||
variant="primary"
|
||||
>
|
||||
|
||||
@@ -23,7 +23,7 @@ export function ValuePicker<T>({ label, icon, options, onChange, variant }: Valu
|
||||
<>
|
||||
{!isPicking && (
|
||||
<FullWidthButtonContainer>
|
||||
<Button size="sm" icon={`fa fa-${icon || 'plus'}`} onClick={() => setIsPicking(true)} variant={variant}>
|
||||
<Button size="sm" icon={icon || 'plus'} onClick={() => setIsPicking(true)} variant={variant}>
|
||||
{label}
|
||||
</Button>
|
||||
</FullWidthButtonContainer>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
export type IconType = 'mono' | 'default';
|
||||
|
||||
export type IconName =
|
||||
| 'fa fa-fw fa-unlock'
|
||||
| 'fa fa-envelope'
|
||||
| 'question-circle'
|
||||
| 'plus'
|
||||
| 'angle-up'
|
||||
@@ -11,12 +13,19 @@ export type IconName =
|
||||
| 'plane'
|
||||
| 'power'
|
||||
| 'trash-alt'
|
||||
| 'plus-square'
|
||||
| 'folder-plus'
|
||||
| 'folder-open'
|
||||
| 'file-copy-alt'
|
||||
| 'exchange-alt'
|
||||
| 'import'
|
||||
| 'exclamation-triangle'
|
||||
| 'times'
|
||||
| 'cloud-upload'
|
||||
| 'step-backward'
|
||||
| 'square-shape'
|
||||
| 'filter'
|
||||
| 'share-alt'
|
||||
| 'tag-alt'
|
||||
| 'forward'
|
||||
| 'check'
|
||||
| 'add-panel'
|
||||
@@ -24,6 +33,8 @@ export type IconName =
|
||||
| 'lock'
|
||||
| 'panel-add'
|
||||
| 'arrow-random'
|
||||
| 'arrow-down'
|
||||
| 'arrow-up'
|
||||
| 'arrow-from-right'
|
||||
| 'keyboard'
|
||||
| 'search'
|
||||
@@ -40,11 +51,15 @@ export type IconName =
|
||||
| 'link'
|
||||
| 'upload'
|
||||
| 'home-alt'
|
||||
| 'channel-add'
|
||||
| 'calendar-alt'
|
||||
| 'calculator-alt'
|
||||
| 'compass'
|
||||
| 'sliders-v-alt'
|
||||
| 'bell'
|
||||
| 'database'
|
||||
| 'user'
|
||||
| 'camera'
|
||||
| 'plug'
|
||||
| 'shield'
|
||||
| 'key-skeleton-alt'
|
||||
@@ -58,22 +73,34 @@ export type IconName =
|
||||
| 'bug'
|
||||
| 'cube'
|
||||
| 'star'
|
||||
| 'list-ul'
|
||||
| 'edit'
|
||||
| 'shield'
|
||||
| 'eye'
|
||||
| 'filter'
|
||||
| 'monitor'
|
||||
| 'plus-circle'
|
||||
| 'arrow-left'
|
||||
| 'repeat'
|
||||
| 'external-link-alt'
|
||||
| 'favorite';
|
||||
|
||||
export const getAvailableIcons = (): IconName[] => [
|
||||
'question-circle',
|
||||
'plane',
|
||||
'plus',
|
||||
'plus-circle',
|
||||
'angle-up',
|
||||
'shield',
|
||||
'angle-down',
|
||||
'angle-left',
|
||||
'angle-right',
|
||||
'calendar-alt',
|
||||
'tag-alt',
|
||||
'calculator-alt',
|
||||
'pen',
|
||||
'repeat',
|
||||
'external-link-alt',
|
||||
'power',
|
||||
'trash-alt',
|
||||
'exclamation-triangle',
|
||||
@@ -81,6 +108,7 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'step-backward',
|
||||
'square-shape',
|
||||
'share-alt',
|
||||
'camera',
|
||||
'forward',
|
||||
'check',
|
||||
'add-panel',
|
||||
@@ -89,6 +117,7 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'panel-add',
|
||||
'arrow-random',
|
||||
'arrow-from-right',
|
||||
'arrow-left',
|
||||
'keyboard',
|
||||
'search',
|
||||
'chart-line',
|
||||
@@ -116,7 +145,9 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'graph-bar',
|
||||
'book',
|
||||
'bolt',
|
||||
'cloud-upload',
|
||||
'comments-alt',
|
||||
'list-ul',
|
||||
'document-info',
|
||||
'info-circle',
|
||||
'bug',
|
||||
@@ -124,6 +155,15 @@ export const getAvailableIcons = (): IconName[] => [
|
||||
'star',
|
||||
'edit',
|
||||
'eye',
|
||||
'channel-add',
|
||||
'monitor',
|
||||
'favorite',
|
||||
'folder-plus',
|
||||
'plus-square',
|
||||
'import',
|
||||
'folder-open',
|
||||
'file-copy-alt',
|
||||
'arrow-down',
|
||||
'arrow-up',
|
||||
'exchange-alt',
|
||||
];
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
||||
children = append(children, &dtos.NavLink{Text: "Folder", SubTitle: "Create a new folder to organize your dashboards", Id: "folder", Icon: "folder-plus", Url: setting.AppSubUrl + "/dashboards/folder/new"})
|
||||
}
|
||||
|
||||
children = append(children, &dtos.NavLink{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "upload", Url: setting.AppSubUrl + "/dashboard/import"})
|
||||
children = append(children, &dtos.NavLink{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "import", Url: setting.AppSubUrl + "/dashboard/import"})
|
||||
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
Text: "Create",
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
SecretFormField,
|
||||
SeriesColorPickerPopoverWithTheme,
|
||||
UnitPicker,
|
||||
Icon,
|
||||
} from '@grafana/ui';
|
||||
import { FunctionEditor } from 'app/plugins/datasource/graphite/FunctionEditor';
|
||||
import ReactProfileWrapper from 'app/features/profile/ReactProfileWrapper';
|
||||
@@ -32,6 +33,13 @@ import { SearchField, SearchResults, SearchResultsFilter } from '../features/sea
|
||||
|
||||
export function registerAngularDirectives() {
|
||||
react2AngularDirective('footer', Footer, []);
|
||||
react2AngularDirective('icon', Icon, [
|
||||
'color',
|
||||
'name',
|
||||
'size',
|
||||
'type',
|
||||
['onClick', { watchDepth: 'reference', wrapApply: true }],
|
||||
]);
|
||||
react2AngularDirective('helpModal', HelpModal, []);
|
||||
react2AngularDirective('sidemenu', SideMenu, []);
|
||||
react2AngularDirective('functionEditor', FunctionEditor, ['func', 'onRemove', 'onMoveLeft', 'onMoveRight']);
|
||||
|
||||
@@ -20,7 +20,7 @@ export const ErrorLoadingChunk: FunctionComponent<Props> = ({ error }) => (
|
||||
<h2 className="page-heading">Grafana has likely been updated. Please try reloading the page.</h2>
|
||||
<br />
|
||||
<div className="gf-form-group">
|
||||
<Button size="md" variant="secondary" icon="fa fa-repeat" onClick={() => window.location.reload()}>
|
||||
<Button size="md" variant="secondary" icon="repeat" onClick={() => window.location.reload()}>
|
||||
Reload
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { MouseEvent, useContext } from 'react';
|
||||
import { CallToActionCard, LinkButton, ThemeContext } from '@grafana/ui';
|
||||
import { CallToActionCard, LinkButton, ThemeContext, Icon, IconName } from '@grafana/ui';
|
||||
import { css } from 'emotion';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
buttonIcon: string;
|
||||
buttonIcon: IconName;
|
||||
buttonLink?: string;
|
||||
buttonTitle: string;
|
||||
onClick?: (event: MouseEvent) => void;
|
||||
@@ -45,7 +45,7 @@ const EmptyListCTA: React.FunctionComponent<Props> = ({
|
||||
<>
|
||||
{proTip ? (
|
||||
<span key="proTipFooter">
|
||||
<i className="fa fa-rocket" />
|
||||
<Icon name="plane" />
|
||||
<> ProTip: {proTip} </>
|
||||
<a href={proTipLink} target={proTipTarget} className="text-link">
|
||||
{proTipLinkTitle}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { FormEvent } from 'react';
|
||||
import { Tab, TabsBar } from '@grafana/ui';
|
||||
import { css } from 'emotion';
|
||||
import { Tab, TabsBar, Icon, IconName } from '@grafana/ui';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { NavModel, NavModelItem, NavModelBreadcrumb } from '@grafana/data';
|
||||
import { CoreEvents } from 'app/types';
|
||||
@@ -65,7 +66,7 @@ const Navigation = ({ main }: { main: NavModelItem }) => {
|
||||
label={child.text}
|
||||
active={child.active}
|
||||
key={`${child.url}-${index}`}
|
||||
icon={child.icon}
|
||||
icon={child.icon as IconName}
|
||||
onChangeTab={() => goToUrl(index)}
|
||||
/>
|
||||
)
|
||||
@@ -113,10 +114,19 @@ export default class PageHeader extends React.Component<Props, any> {
|
||||
}
|
||||
|
||||
renderHeaderTitle(main: NavModelItem) {
|
||||
const iconClassName =
|
||||
main.icon === 'grafana'
|
||||
? css`
|
||||
margin-top: 12px;
|
||||
`
|
||||
: css`
|
||||
margin-top: 14px;
|
||||
`;
|
||||
|
||||
return (
|
||||
<div className="page-header__inner">
|
||||
<span className="page-header__logo">
|
||||
{main.icon && <i className={`page-header__icon ${main.icon}`} />}
|
||||
{main.icon && <Icon name={main.icon as IconName} size="xxl" type="mono" className={iconClassName} />}
|
||||
{main.img && <img className="page-header__img" src={main.img} />}
|
||||
</span>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import { LegacyForms, Icon } from '@grafana/ui';
|
||||
import { dashboardPermissionLevels } from 'app/types/acl';
|
||||
const { Select } = LegacyForms;
|
||||
|
||||
@@ -15,7 +15,7 @@ export default class DisabledPermissionListItem extends Component<Props, any> {
|
||||
return (
|
||||
<tr className="gf-form-disabled">
|
||||
<td style={{ width: '1%' }}>
|
||||
<i style={{ width: '25px', height: '25px' }} className="gicon gicon-shield" />
|
||||
<Icon size="lg" name="shield" />
|
||||
</td>
|
||||
<td style={{ width: '90%' }}>
|
||||
{item.name}
|
||||
@@ -36,7 +36,7 @@ export default class DisabledPermissionListItem extends Component<Props, any> {
|
||||
</td>
|
||||
<td>
|
||||
<button className="btn btn-inverse btn-small">
|
||||
<i className="fa fa-lock" />
|
||||
<Icon name="lock" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import { LegacyForms, Icon } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
|
||||
import { FolderInfo } from 'app/types';
|
||||
@@ -17,10 +17,10 @@ function ItemAvatar({ item }: { item: DashboardAcl }) {
|
||||
return <img className="filter-table__avatar" src={item.teamAvatarUrl} />;
|
||||
}
|
||||
if (item.role === 'Editor') {
|
||||
return <i style={{ width: '25px', height: '25px' }} className="gicon gicon-editor" />;
|
||||
return <Icon size="lg" name="edit" />;
|
||||
}
|
||||
|
||||
return <i style={{ width: '25px', height: '25px' }} className="gicon gicon-viewer" />;
|
||||
return <Icon size="lg" name="eye" />;
|
||||
}
|
||||
|
||||
function ItemDescription({ item }: { item: DashboardAcl }) {
|
||||
@@ -89,11 +89,11 @@ export default class PermissionsListItem extends PureComponent<Props> {
|
||||
<td>
|
||||
{!item.inherited ? (
|
||||
<a className="btn btn-danger btn-small" onClick={this.onRemoveItem}>
|
||||
<i className="fa fa-remove" />
|
||||
<Icon name="times" />
|
||||
</a>
|
||||
) : (
|
||||
<button className="btn btn-inverse btn-small">
|
||||
<i className="fa fa-lock" />
|
||||
<Icon name="lock" />
|
||||
</button>
|
||||
)}
|
||||
</td>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { escapeStringForRegex } from '@grafana/data';
|
||||
// Components
|
||||
import { TagOption } from './TagOption';
|
||||
import { TagBadge } from './TagBadge';
|
||||
import { resetSelectStyles, LegacyForms } from '@grafana/ui';
|
||||
import { resetSelectStyles, LegacyForms, Icon } from '@grafana/ui';
|
||||
const { IndicatorsContainer, NoOptionsMessage } = LegacyForms;
|
||||
|
||||
export interface TermCount {
|
||||
@@ -90,7 +90,7 @@ export class TagFilter extends React.Component<Props, any> {
|
||||
<div className="tag-filter">
|
||||
<AsyncSelect {...selectOptions} />
|
||||
</div>
|
||||
<i className="gf-form-input-icon fa fa-tag" />
|
||||
<Icon className="gf-form-input-icon" name="tag-alt" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import Drop from 'tether-drop';
|
||||
export function infoPopover() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<i class="fa fa-info-circle"></i>',
|
||||
template: `<icon name="'info-circle'"></icon>`,
|
||||
transclude: true,
|
||||
link: (scope: any, elem: any, attrs: any, ctrl: any, transclude: any) => {
|
||||
const offset = attrs.offset || '0 -10px';
|
||||
|
||||
@@ -1,17 +1,38 @@
|
||||
<div class="dashboard-list">
|
||||
<div class="page-action-bar page-action-bar--narrow" ng-hide="ctrl.folderId && !ctrl.hasFilters && ctrl.sections.length === 0">
|
||||
<div
|
||||
class="page-action-bar page-action-bar--narrow"
|
||||
ng-hide="ctrl.folderId && !ctrl.hasFilters && ctrl.sections.length === 0"
|
||||
>
|
||||
<label class="gf-form gf-form--grow gf-form--has-input-icon">
|
||||
<input type="text" class="gf-form-input max-width-30" placeholder="Search dashboards by name" tabindex="1" give-focus="true" ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.onQueryChange()" />
|
||||
<i class="gf-form-input-icon fa fa-search"></i>
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input max-width-30"
|
||||
placeholder="Search dashboards by name"
|
||||
tabindex="1"
|
||||
give-focus="true"
|
||||
ng-model="ctrl.query.query"
|
||||
ng-model-options="{ debounce: 500 }"
|
||||
spellcheck="false"
|
||||
ng-change="ctrl.onQueryChange()"
|
||||
/>
|
||||
<icon class="gf-form-input-icon" name="'search'"></icon>
|
||||
</label>
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-primary" ng-href="{{ctrl.createDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
|
||||
<a
|
||||
class="btn btn-primary"
|
||||
ng-href="{{ctrl.createDashboardUrl()}}"
|
||||
ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave"
|
||||
>
|
||||
New Dashboard
|
||||
</a>
|
||||
<a class="btn btn-primary" href="dashboards/folder/new" ng-if="!ctrl.folderId && ctrl.isEditor">
|
||||
New Folder
|
||||
</a>
|
||||
<a class="btn btn-primary" href="{{ctrl.importDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
|
||||
<a
|
||||
class="btn btn-primary"
|
||||
href="{{ctrl.importDashboardUrl()}}"
|
||||
ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave"
|
||||
>
|
||||
Import
|
||||
</a>
|
||||
</div>
|
||||
@@ -25,22 +46,20 @@
|
||||
<div class="gf-form-input gf-form-input--plaintext" ng-show="ctrl.query.tag.length > 0">
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="tagName" class="tag label label-tag">
|
||||
<i class="fa fa-remove"></i> {{tagName}}
|
||||
<icon name="'times'"></icon> {{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-show="ctrl.query.starred">
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" ng-click="ctrl.removeStarred()">
|
||||
<i class="fa fa-fw fa-check"></i> Starred
|
||||
</a>
|
||||
<a class="pointer" ng-click="ctrl.removeStarred()"> <icon name="'check'"></icon> Starred </a>
|
||||
</label>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" ng-click="ctrl.clearFilters()" bs-tooltip="'Clear current search query and filters'">
|
||||
<i class="fa fa-remove"></i> Clear
|
||||
<icon name="'times'"></icon> Clear
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
@@ -53,25 +72,25 @@
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<div class="search-results" ng-show="!ctrl.folderId && !ctrl.hasFilters && ctrl.sections.length === 0">
|
||||
<div class="search-results" ng-show="!ctrl.folderId && !ctrl.hasFilters && ctrl.sections.length === 0">
|
||||
<em class="muted">
|
||||
No dashboards found.
|
||||
No dashboards found.
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<div class="search-results" ng-show="ctrl.sections.length > 0">
|
||||
<search-filters
|
||||
on-select-all-changed="ctrl.onSelectAllChanged"
|
||||
all-checked="ctrl.selectAllChecked"
|
||||
can-move="ctrl.canMove"
|
||||
can-delete="ctrl.canDelete"
|
||||
move-to="ctrl.moveTo"
|
||||
delete-item="ctrl.delete"
|
||||
tag-filter-options="ctrl.tagFilterOptions"
|
||||
selected-starred-filter="ctrl.selectedStarredFilter"
|
||||
on-starred-filter-change="ctrl.onStarredFilterChange"
|
||||
selected-tag-filter="ctrl.selectedTagFilter"
|
||||
on-tagfilter-change="ctrl.onTagFilterChange"
|
||||
on-select-all-changed="ctrl.onSelectAllChanged"
|
||||
all-checked="ctrl.selectAllChecked"
|
||||
can-move="ctrl.canMove"
|
||||
can-delete="ctrl.canDelete"
|
||||
move-to="ctrl.moveTo"
|
||||
delete-item="ctrl.delete"
|
||||
tag-filter-options="ctrl.tagFilterOptions"
|
||||
selected-starred-filter="ctrl.selectedStarredFilter"
|
||||
on-starred-filter-change="ctrl.onStarredFilterChange"
|
||||
selected-tag-filter="ctrl.selectedTagFilter"
|
||||
on-tagfilter-change="ctrl.onTagFilterChange"
|
||||
/>
|
||||
<div class="search-results-container">
|
||||
<search-results
|
||||
@@ -83,13 +102,12 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.canSave && ctrl.folderId && !ctrl.hasFilters && ctrl.sections.length === 0">
|
||||
<empty-list-cta
|
||||
title="'This folder doesn\'t have any dashboards yet'"
|
||||
buttonIcon="'gicon gicon-dashboard-new'"
|
||||
buttonIcon="'plus-circle'"
|
||||
buttonLink="'dashboard/new?folderId={{ctrl.folderId}}'"
|
||||
buttonTitle="'Create Dashboard'"
|
||||
proTip="'Add/move dashboards to your folder at ->'"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
<div class="search-backdrop" ng-if="ctrl.isOpen"></div>
|
||||
|
||||
<div class="search-container" ng-if="ctrl.isOpen">
|
||||
|
||||
<search-field
|
||||
query="ctrl.query"
|
||||
autoFocus="ctrl.giveSearchFocus"
|
||||
@@ -10,8 +8,7 @@
|
||||
on-key-down="ctrl.onKeyDown"
|
||||
/>
|
||||
|
||||
|
||||
<div class="search-dropdown">
|
||||
<div class="search-dropdown">
|
||||
<div class="search-dropdown__col_1">
|
||||
<div class="search-results-scroller">
|
||||
<div class="search-results-container" grafana-scrollbar>
|
||||
@@ -29,32 +26,38 @@
|
||||
<div class="search-dropdown__col_2">
|
||||
<div class="search-filter-box" ng-click="ctrl.onFilterboxClick()">
|
||||
<div class="search-filter-box__header">
|
||||
<i class="fa fa-filter"></i>
|
||||
<icon name="'filter'"></icon>
|
||||
Filter by:
|
||||
<a class="pointer pull-right small" ng-click="ctrl.clearSearchFilter()">
|
||||
<i class="fa fa-remove"></i> Clear
|
||||
<icon name="'times'" size="'sm'"></icon> Clear
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<tag-filter tags="ctrl.query.tags" tagOptions="ctrl.getTags" on-change="ctrl.onTagFiltersChanged">
|
||||
</tag-filter>
|
||||
<tag-filter tags="ctrl.query.tags" tagOptions="ctrl.getTags" on-change="ctrl.onTagFiltersChanged"> </tag-filter>
|
||||
</div>
|
||||
|
||||
<div class="search-filter-box" ng-if="ctrl.isEditor || ctrl.hasEditPermissionInFolders">
|
||||
<a href="dashboard/new" class="search-filter-box-link">
|
||||
<i class="gicon gicon-dashboard-new"></i> New dashboard
|
||||
<icon name="'plus-square'" size="'xl'" style="margin-right: 8px;"></icon> New dashboard
|
||||
</a>
|
||||
<a href="dashboards/folder/new" class="search-filter-box-link" ng-if="ctrl.isEditor">
|
||||
<i class="gicon gicon-folder-new"></i> New folder
|
||||
<icon name="'folder-plus'" 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">
|
||||
<i class="gicon gicon-dashboard-import"></i> Import dashboard
|
||||
<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
|
||||
</a>
|
||||
<a class="search-filter-box-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
<img src="public/img/icn-dashboard-tiny.svg" width="20" /> Find dashboards on Grafana.com
|
||||
<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
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
<div ng-repeat="section in ctrl.results" class="search-section">
|
||||
<div class="search-section__header pointer" ng-hide="section.hideHeader" ng-class="{'selected': section.selected}" ng-click="ctrl.toggleFolderExpand(section)">
|
||||
<div
|
||||
class="search-section__header pointer"
|
||||
ng-hide="section.hideHeader"
|
||||
ng-class="{'selected': section.selected}"
|
||||
ng-click="ctrl.toggleFolderExpand(section)"
|
||||
>
|
||||
<div ng-click="ctrl.toggleSelection(section, $event)" class="center-vh">
|
||||
<gf-form-checkbox
|
||||
ng-show="ctrl.editable"
|
||||
on-change="ctrl.selectionChanged($event)"
|
||||
checked="section.checked"
|
||||
switch-class="gf-form-checkbox--transparent">
|
||||
ng-show="ctrl.editable"
|
||||
on-change="ctrl.selectionChanged($event)"
|
||||
checked="section.checked"
|
||||
switch-class="gf-form-checkbox--transparent"
|
||||
>
|
||||
</gf-form-checkbox>
|
||||
</div>
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<a ng-show="section.url" href="{{section.url}}" class="search-section__header__link">
|
||||
<i class="gicon gicon-cog"></i>
|
||||
<icon name="'cog'"></icon>
|
||||
</a>
|
||||
<i class="fa fa-angle-down search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-angle-right search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
<icon class="search-section__header__toggle" name="'angle-down'" ng-show="section.expanded"></icon>
|
||||
<icon class="search-section__header__toggle" name="'angle-right'" ng-hide="section.expanded"></icon>
|
||||
</div>
|
||||
|
||||
<div class="search-section__header" ng-show="section.hideHeader"></div>
|
||||
|
||||
<div ng-if="section.expanded">
|
||||
<a ng-repeat="item in section.items" class="search-item search-item--indent" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}" aria-label={{ctrl.selectors.dashboards(item.title)}}>
|
||||
<a
|
||||
ng-repeat="item in section.items"
|
||||
class="search-item search-item--indent"
|
||||
ng-class="{'selected': item.selected}"
|
||||
ng-href="{{::item.url}}"
|
||||
aria-label="{{ctrl.selectors.dashboards(item.title)}}"
|
||||
>
|
||||
<div ng-click="ctrl.toggleSelection(item, $event)" class="center-vh">
|
||||
<gf-form-checkbox
|
||||
ng-show="ctrl.editable"
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="item.checked"
|
||||
switch-class="gf-form-checkbox--transparent">
|
||||
ng-show="ctrl.editable"
|
||||
on-change="ctrl.selectionChanged()"
|
||||
checked="item.checked"
|
||||
switch-class="gf-form-checkbox--transparent"
|
||||
>
|
||||
</gf-form-checkbox>
|
||||
</div>
|
||||
<span class="search-item__icon">
|
||||
@@ -37,11 +50,15 @@
|
||||
<span class="search-item__body-folder-title">{{::item.folderTitle}}</span>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.selectTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
<span
|
||||
ng-click="ctrl.selectTag(tag, $event)"
|
||||
ng-repeat="tag in item.tags"
|
||||
tag-color-from-name="tag"
|
||||
class="label label-tag"
|
||||
>
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export class InvitedCtrl {
|
||||
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
text: 'Invite',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
||||
@@ -21,7 +21,7 @@ export class ResetPasswordCtrl {
|
||||
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
text: 'Reset Password',
|
||||
subTitle: 'Reset your Grafana password',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
||||
@@ -29,7 +29,7 @@ export class SignUpCtrl {
|
||||
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
text: 'Sign Up',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
||||
@@ -3,7 +3,7 @@ import { css, cx } from 'emotion';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { Pagination, Tooltip, HorizontalGroup, stylesFactory, LinkButton, Input } from '@grafana/ui';
|
||||
import { Pagination, Tooltip, HorizontalGroup, stylesFactory, LinkButton, Input, Icon } from '@grafana/ui';
|
||||
import { StoreState, UserDTO } from '../../types';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { getNavModel } from '../../core/selectors/navModel';
|
||||
@@ -51,7 +51,7 @@ const UserListAdminPageUnConnected: React.FC<Props> = props => {
|
||||
value={props.query}
|
||||
spellCheck={false}
|
||||
onChange={event => props.changeQuery(event.currentTarget.value)}
|
||||
prefix={<i className="fa fa-search" />}
|
||||
prefix={<Icon name="search" />}
|
||||
/>
|
||||
<LinkButton href="admin/users/create" variant="primary">
|
||||
New user
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { ConfirmButton, RadioButtonGroup } from '@grafana/ui';
|
||||
import { ConfirmButton, RadioButtonGroup, Icon } from '@grafana/ui';
|
||||
import { cx } from 'emotion';
|
||||
|
||||
interface Props {
|
||||
@@ -73,7 +73,7 @@ export class UserPermissions extends PureComponent<Props, State> {
|
||||
<td colSpan={2}>
|
||||
{isGrafanaAdmin ? (
|
||||
<>
|
||||
<i className="gicon gicon-shield" /> Yes
|
||||
<Icon name="shield" /> Yes
|
||||
</>
|
||||
) : (
|
||||
<>No</>
|
||||
|
||||
@@ -52,11 +52,7 @@ exports[`ServerStats Should render table with stats 1`] = `
|
||||
>
|
||||
<span
|
||||
className="page-header__logo"
|
||||
>
|
||||
<i
|
||||
className="page-header__icon fa fa-fw fa-warning"
|
||||
/>
|
||||
</span>
|
||||
/>
|
||||
<div
|
||||
className="page-header__info-block"
|
||||
>
|
||||
@@ -100,12 +96,9 @@ exports[`ServerStats Should render table with stats 1`] = `
|
||||
className="css-payll4"
|
||||
>
|
||||
<li
|
||||
className="css-1aiaexb"
|
||||
className="css-vohy86"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="icon"
|
||||
/>
|
||||
Admin
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { FC } from 'react';
|
||||
import { LdapPermissions } from 'app/types';
|
||||
import { Icon } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
permissions: LdapPermissions;
|
||||
@@ -21,7 +22,7 @@ export const LdapUserPermissions: FC<Props> = ({ permissions }) => {
|
||||
<td>
|
||||
{permissions.isGrafanaAdmin ? (
|
||||
<>
|
||||
<i className="gicon gicon-shield" /> Yes
|
||||
<Icon name="shield" /> Yes
|
||||
</>
|
||||
) : (
|
||||
'No'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect, MapStateToProps, MapDispatchToProps } from 'react-redux';
|
||||
import { css } from 'emotion';
|
||||
import { Alert, Button } from '@grafana/ui';
|
||||
import { Alert, Button, IconName } from '@grafana/ui';
|
||||
|
||||
import { AngularComponent, getAngularLoader, getDataSourceSrv } from '@grafana/runtime';
|
||||
import appEvents from 'app/core/app_events';
|
||||
@@ -130,7 +130,7 @@ class UnConnectedAlertTab extends PureComponent<Props, State> {
|
||||
title: 'Delete Alert',
|
||||
text: 'Are you sure you want to delete this alert rule?',
|
||||
text2: 'You need to save dashboard for the delete to take effect',
|
||||
icon: 'fa-trash',
|
||||
icon: 'trash-alt',
|
||||
yesText: 'Delete',
|
||||
onConfirm: () => {
|
||||
delete panel.alert;
|
||||
@@ -178,7 +178,7 @@ class UnConnectedAlertTab extends PureComponent<Props, State> {
|
||||
<h2>{validatonMessage}</h2>
|
||||
<br />
|
||||
<div className="gf-form-group">
|
||||
<Button size={'md'} variant={'secondary'} icon="fa fa-arrow-left" onClick={this.switchToQueryTab}>
|
||||
<Button size={'md'} variant={'secondary'} icon="arrow-left" onClick={this.switchToQueryTab}>
|
||||
Go back to Queries
|
||||
</Button>
|
||||
</div>
|
||||
@@ -199,7 +199,7 @@ class UnConnectedAlertTab extends PureComponent<Props, State> {
|
||||
|
||||
const model = {
|
||||
title: 'Panel has no alert rule defined',
|
||||
buttonIcon: 'gicon gicon-alert',
|
||||
buttonIcon: 'bell' as IconName,
|
||||
onClick: this.onAddAlert,
|
||||
buttonTitle: 'Create Alert',
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
|
||||
<div ng-if="ctrl.notifications.length">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer">
|
||||
</div>
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
|
||||
<a href="alerting/notification/new" class="btn btn-primary">
|
||||
New channel
|
||||
@@ -46,14 +44,14 @@
|
||||
</div>
|
||||
<div ng-if="ctrl.notifications.length === 0">
|
||||
<empty-list-cta
|
||||
title= "'There are no notification channels defined yet'"
|
||||
buttonIcon= "'gicon gicon-alert-notification-channel'"
|
||||
buttonLink= "'alerting/notification/new'"
|
||||
buttonTitle= "'Add channel'"
|
||||
proTip= "'You can include images in your alert notifications.'"
|
||||
proTipLink= "'http://docs.grafana.org/alerting/notifications/'"
|
||||
proTipLinkTitle= "'Learn more'"
|
||||
proTipTarget= "'_blank'"
|
||||
title="'There are no notification channels defined yet'"
|
||||
buttonIcon="'channel-add'"
|
||||
buttonLink="'alerting/notification/new'"
|
||||
buttonTitle="'Add channel'"
|
||||
proTip="'You can include images in your alert notifications.'"
|
||||
proTipLink="'http://docs.grafana.org/alerting/notifications/'"
|
||||
proTipLinkTitle="'Learn more'"
|
||||
proTipTarget="'_blank'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -151,7 +151,7 @@ export class ApiKeysPage extends PureComponent<Props, any> {
|
||||
{!isAdding && (
|
||||
<EmptyListCTA
|
||||
title="You haven't added any API Keys yet."
|
||||
buttonIcon="gicon gicon-apikeys"
|
||||
buttonIcon="key-skeleton-alt"
|
||||
buttonLink="#"
|
||||
onClick={this.onToggleAdding}
|
||||
buttonTitle=" New API Key"
|
||||
|
||||
@@ -36,7 +36,7 @@ exports[`Render should render CTA if there are no API keys 1`] = `
|
||||
isLoading={false}
|
||||
>
|
||||
<EmptyListCTA
|
||||
buttonIcon="gicon gicon-apikeys"
|
||||
buttonIcon="key-skeleton-alt"
|
||||
buttonLink="#"
|
||||
buttonTitle=" New API Key"
|
||||
onClick={[Function]}
|
||||
|
||||
@@ -99,6 +99,10 @@ class DashNav extends PureComponent<Props> {
|
||||
/* Hard-coded value so we don't have to wrap whole component in withTheme because of 1 variable */
|
||||
const iconClassName = css`
|
||||
margin-right: 8px;
|
||||
margin-bottom: -1px;
|
||||
`;
|
||||
const mainIconClassName = css`
|
||||
margin-right: 8px;
|
||||
`;
|
||||
|
||||
const folderTitle = dashboard.meta.folderTitle;
|
||||
@@ -108,7 +112,7 @@ class DashNav extends PureComponent<Props> {
|
||||
<>
|
||||
<div>
|
||||
<div className="navbar-page-btn">
|
||||
{!isFullscreen && <Icon name="apps" size="xl" className={iconClassName} />}
|
||||
{!isFullscreen && <Icon name="apps" size="xl" className={mainIconClassName} />}
|
||||
{haveFolder && (
|
||||
<>
|
||||
<a className="navbar-page-btn__folder" onClick={this.onFolderNameClick}>
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import { Tooltip, Icon } from '@grafana/ui';
|
||||
import { SlideDown } from 'app/core/components/Animations/SlideDown';
|
||||
import { StoreState, FolderInfo } from 'app/types';
|
||||
import { DashboardAcl, PermissionLevel, NewDashboardAclItem } from 'app/types/acl';
|
||||
@@ -71,9 +71,7 @@ export class DashboardPermissions extends PureComponent<Props, State> {
|
||||
<div className="page-action-bar">
|
||||
<h3 className="d-inline-block">Permissions</h3>
|
||||
<Tooltip placement="auto" content={<PermissionsInfo />}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
<button className="btn btn-primary pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { config } from 'app/core/config';
|
||||
import { css } from 'emotion';
|
||||
import { TabsBar, Tab, stylesFactory, TabContent, TransformationsEditor } from '@grafana/ui';
|
||||
import { TabsBar, Tab, stylesFactory, TabContent, TransformationsEditor, IconName } from '@grafana/ui';
|
||||
import { DataTransformerConfig, LoadingState, PanelData } from '@grafana/data';
|
||||
import { PanelEditorTab, PanelEditorTabId } from './types';
|
||||
import { DashboardModel } from '../../state';
|
||||
@@ -40,7 +40,7 @@ export const PanelEditorTabs: React.FC<PanelEditorTabsProps> = ({ panel, dashboa
|
||||
label={tab.text}
|
||||
active={tab.active}
|
||||
onChangeTab={() => onChangeTab(tab)}
|
||||
icon={tab.icon}
|
||||
icon={tab.icon as IconName}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Switch, LegacyForms } from '@grafana/ui';
|
||||
import { Switch, LegacyForms, Icon } from '@grafana/ui';
|
||||
const { Select } = LegacyForms;
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
@@ -79,9 +79,7 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<div className="share-modal-big-icon">
|
||||
<i className="gicon gicon-link"></i>
|
||||
</div>
|
||||
<Icon name="link" className="share-modal-big-icon" size="xxl" />
|
||||
<div className="share-modal-content">
|
||||
<div className="gf-form-group">
|
||||
<Switch
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Button, Switch } from '@grafana/ui';
|
||||
import { Button, Switch, Icon } from '@grafana/ui';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal';
|
||||
import { appEvents } from 'app/core/core';
|
||||
@@ -90,9 +90,7 @@ export class ShareExport extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<div className="share-modal-big-icon">
|
||||
<i className="fa fa-cloud-upload"></i>
|
||||
</div>
|
||||
<Icon name="cloud-upload" size="xxl" className="share-modal-big-icon" />
|
||||
<div className="share-modal-content">
|
||||
<Switch
|
||||
labelClass="width-16"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { e2e } from '@grafana/e2e';
|
||||
import { Switch, LegacyForms, ClipboardButton } from '@grafana/ui';
|
||||
import { Switch, LegacyForms, ClipboardButton, Icon } from '@grafana/ui';
|
||||
const { Select } = LegacyForms;
|
||||
import { SelectableValue, PanelModel, AppEvents } from '@grafana/data';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
@@ -90,9 +90,7 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<div className="share-modal-big-icon">
|
||||
<i className="gicon gicon-link"></i>
|
||||
</div>
|
||||
<Icon name="link" className="share-modal-big-icon" size="xxl" />
|
||||
<div className="share-modal-content">
|
||||
<p className="share-modal-info-text">
|
||||
Create a direct link to this dashboard or panel, customized with the options below.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Button, ClipboardButton, LinkButton, LegacyForms } from '@grafana/ui';
|
||||
import { Button, ClipboardButton, LinkButton, LegacyForms, Icon } from '@grafana/ui';
|
||||
const { Select, Input } = LegacyForms;
|
||||
import { AppEvents, SelectableValue } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
@@ -302,9 +302,13 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<div className="share-modal-big-icon">
|
||||
{isLoading ? <i className="fa fa-spinner fa-spin"></i> : <i className="gicon gicon-snapshots"></i>}
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<div className="share-modal-big-icon">
|
||||
<i className="fa fa-spinner fa-spin"></i>
|
||||
</div>
|
||||
) : (
|
||||
<Icon name="camera" className="share-modal-big-icon" size="xxl" />
|
||||
)}
|
||||
<div className="share-modal-content">
|
||||
{step === 1 && this.renderStep1()}
|
||||
{step === 2 && this.renderStep2()}
|
||||
|
||||
@@ -20,7 +20,7 @@ export const PanelHeaderMenuItem: FC<Props & PanelMenuItem> = props => {
|
||||
`;
|
||||
const shortcutIconClassName = css`
|
||||
position: absolute;
|
||||
margin-top: 3px;
|
||||
top: 7px;
|
||||
right: ${theme.spacing.xs};
|
||||
color: ${theme.colors.textWeak};
|
||||
`;
|
||||
|
||||
@@ -9,6 +9,7 @@ import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import DataSourcesList from './DataSourcesList';
|
||||
// Types
|
||||
import { DataSourceSettings, NavModel } from '@grafana/data';
|
||||
import { IconName } from '@grafana/ui';
|
||||
import { StoreState } from 'app/types';
|
||||
import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
|
||||
// Actions
|
||||
@@ -37,7 +38,7 @@ export interface Props {
|
||||
|
||||
const emptyListModel = {
|
||||
title: 'There are no data sources defined yet',
|
||||
buttonIcon: 'gicon gicon-datasources',
|
||||
buttonIcon: 'database' as IconName,
|
||||
buttonLink: 'datasources/new',
|
||||
buttonTitle: 'Add data source',
|
||||
proTip: 'You can also define data sources through configuration files.',
|
||||
|
||||
@@ -143,7 +143,7 @@ const DataSourceTypeCard: FC<DataSourceTypeCardProps> = props => {
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
onClick={onLearnMoreClick}
|
||||
icon="fa fa-external-link"
|
||||
icon="external-link-alt"
|
||||
>
|
||||
{learnMoreLink.name}
|
||||
</LinkButton>
|
||||
|
||||
@@ -23,7 +23,7 @@ export const NoDataSourceCallToAction = () => {
|
||||
);
|
||||
|
||||
const ctaElement = (
|
||||
<LinkButton size="lg" href="/datasources/new" icon="gicon gicon-datasources">
|
||||
<LinkButton size="lg" href="/datasources/new" icon="database">
|
||||
Add data source
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
@@ -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 } from '@grafana/ui';
|
||||
import { TabsBar, Tab, TabContent, Themeable, CustomScrollbar, IconName } from '@grafana/ui';
|
||||
|
||||
//Components
|
||||
import { RichHistorySettings } from './RichHistorySettings';
|
||||
@@ -216,7 +216,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
|
||||
label={t.label}
|
||||
active={t.value === activeTab}
|
||||
onChangeTab={() => this.onSelectTab(t)}
|
||||
icon={t.icon}
|
||||
icon={t.icon as IconName}
|
||||
/>
|
||||
))}
|
||||
<div className={styles.close} onClick={onClose}>
|
||||
|
||||
@@ -63,7 +63,7 @@ export function RichHistorySettings(props: RichHistorySettingsProps) {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to permanently delete your query history?',
|
||||
yesText: 'Delete',
|
||||
icon: 'fa-trash',
|
||||
icon: 'trash-alt',
|
||||
onConfirm: () => {
|
||||
deleteRichHistory();
|
||||
appEvents.emit(AppEvents.alertSuccess, ['Query history deleted']);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { connect } from 'react-redux';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import { Tooltip, Icon } from '@grafana/ui';
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { SlideDown } from 'app/core/components/Animations/SlideDown';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
@@ -91,9 +91,7 @@ export class FolderPermissions extends PureComponent<Props, State> {
|
||||
<div className="page-action-bar">
|
||||
<h3 className="page-sub-heading">Folder Permissions</h3>
|
||||
<Tooltip placement="auto" content={<PermissionsInfo />}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
<button className="btn btn-primary pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
|
||||
|
||||
@@ -4,7 +4,7 @@ export class FolderPageLoader {
|
||||
load(ctrl: any, uid: any, activeChildId: any) {
|
||||
ctrl.navModel = {
|
||||
main: {
|
||||
icon: 'fa fa-folder-open',
|
||||
icon: 'folder',
|
||||
id: 'manage-folder',
|
||||
subTitle: 'Manage folder dashboards & permissions',
|
||||
url: '',
|
||||
@@ -13,21 +13,21 @@ export class FolderPageLoader {
|
||||
children: [
|
||||
{
|
||||
active: activeChildId === 'manage-folder-dashboards',
|
||||
icon: 'fa fa-fw fa-th-large',
|
||||
icon: 'apps',
|
||||
id: 'manage-folder-dashboards',
|
||||
text: 'Dashboards',
|
||||
url: 'dashboards',
|
||||
},
|
||||
{
|
||||
active: activeChildId === 'manage-folder-permissions',
|
||||
icon: 'fa fa-fw fa-lock',
|
||||
icon: 'lock',
|
||||
id: 'manage-folder-permissions',
|
||||
text: 'Permissions',
|
||||
url: 'dashboards/permissions',
|
||||
},
|
||||
{
|
||||
active: activeChildId === 'manage-folder-settings',
|
||||
icon: 'gicon gicon-cog',
|
||||
icon: 'cog',
|
||||
id: 'manage-folder-settings',
|
||||
text: 'Settings',
|
||||
url: 'dashboards/settings',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { NavModelItem, NavModel } from '@grafana/data';
|
||||
|
||||
export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
return {
|
||||
icon: 'fa fa-folder-open',
|
||||
icon: 'folder',
|
||||
id: 'manage-folder',
|
||||
subTitle: 'Manage folder dashboards & permissions',
|
||||
url: '',
|
||||
@@ -12,21 +12,21 @@ export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
children: [
|
||||
{
|
||||
active: false,
|
||||
icon: 'fa fa-fw fa-th-large',
|
||||
icon: 'apps',
|
||||
id: `folder-dashboards-${folder.uid}`,
|
||||
text: 'Dashboards',
|
||||
url: folder.url,
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
icon: 'fa fa-fw fa-lock',
|
||||
icon: 'lock',
|
||||
id: `folder-permissions-${folder.uid}`,
|
||||
text: 'Permissions',
|
||||
url: `${folder.url}/permissions`,
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
icon: 'gicon gicon-cog',
|
||||
icon: 'cog',
|
||||
id: `folder-settings-${folder.uid}`,
|
||||
text: 'Settings',
|
||||
url: `${folder.url}/settings`,
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<table class="filter-table">
|
||||
<table class="filter-table">
|
||||
<thead>
|
||||
<th><strong>Name</strong></th>
|
||||
<th><strong>Snapshot url</strong></th>
|
||||
<th style="width: 70px"></th>
|
||||
<th style="width: 30px"></th>
|
||||
<th style="width: 25px"></th>
|
||||
</thead>
|
||||
<tr ng-repeat="snapshot in ctrl.snapshots">
|
||||
</thead>
|
||||
<tr ng-repeat="snapshot in ctrl.snapshots">
|
||||
<td>
|
||||
<a href="{{snapshot.url}}">{{snapshot.name}}</a>
|
||||
</td>
|
||||
<td >
|
||||
<td>
|
||||
<a href="{{snapshot.url}}">{{snapshot.url}}</a>
|
||||
</td>
|
||||
<td>
|
||||
@@ -21,18 +21,17 @@
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{{snapshot.url}}" class="btn btn-inverse btn-small">
|
||||
<i class="gicon gicon-viewer"></i>
|
||||
<icon name="'eye'" style="margin-right: 4px; margin-bottom: 2px;"></icon>
|
||||
View
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<td class="text-right">
|
||||
<a ng-click="ctrl.removeSnapshot(snapshot)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
<icon name="'times'"></icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<footer />
|
||||
|
||||
@@ -10,7 +10,7 @@ export class SelectOrgCtrl {
|
||||
|
||||
$scope.navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
subTitle: 'Preferences',
|
||||
text: 'Select active organization',
|
||||
},
|
||||
|
||||
@@ -1,104 +1,124 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body" ng-form="ctrl.playlistEditForm">
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Playlist</h3>
|
||||
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Playlist</h3>
|
||||
<p class="playlist-description">
|
||||
A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational
|
||||
awareness, or just show off your metrics to your team or visitors.
|
||||
</p>
|
||||
|
||||
<p class="playlist-description">A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational awareness, or just show off your metrics to your team or visitors.</p>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Name</span>
|
||||
<input type="text" required ng-model="ctrl.playlist.name" class="gf-form-input max-width-21" />
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Interval</span>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
ng-model="ctrl.playlist.interval"
|
||||
placeholder="5m"
|
||||
class="gf-form-input max-width-21"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Name</span>
|
||||
<input type="text" required ng-model="ctrl.playlist.name" class="gf-form-input max-width-21">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Interval</span>
|
||||
<input type="text" required ng-model="ctrl.playlist.interval" placeholder="5m" class="gf-form-input max-width-21">
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Dashboards</h3>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Dashboards</h3>
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.playlistItems">
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_id'">
|
||||
<icon name="'apps'"></icon> {{playlistItem.title}}
|
||||
</td>
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_tag'">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title">
|
||||
<icon name="'tag-alt'"></icon>
|
||||
<span>{{playlistItem.title}}</span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.playlistItems">
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_id'">
|
||||
<i class="gicon gicon-dashboard"></i> {{playlistItem.title}}
|
||||
</td>
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_tag'">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{playlistItem.title}}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="selected-playlistitem-settings">
|
||||
<button class="btn btn-inverse btn-small" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)">
|
||||
<icon name="'arrow-up'"></icon>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-small" ng-hide="$last" ng-click="ctrl.movePlaylistItemDown(playlistItem)">
|
||||
<icon name="'arrow-down'"></icon>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-small" ng-click="ctrl.removePlaylistItem(playlistItem)">
|
||||
<icon name="'times'"></icon>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="ctrl.playlistItems.length === 0">
|
||||
<td><em>Playlist is empty, add dashboards below.</em></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<td class="selected-playlistitem-settings">
|
||||
<button class="btn btn-inverse btn-small" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)">
|
||||
<i class="fa fa-arrow-up"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-small" ng-hide="$last" ng-click="ctrl.movePlaylistItemDown(playlistItem)">
|
||||
<i class="fa fa-arrow-down"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-small" ng-click="ctrl.removePlaylistItem(playlistItem)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="ctrl.playlistItems.length === 0">
|
||||
<td><em>Playlist is empty, add dashboards below.</em></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Add dashboards</h3>
|
||||
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Add dashboards</h3>
|
||||
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
|
||||
<div ng-if="ctrl.filteredDashboards.length > 0">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredDashboards">
|
||||
<td>
|
||||
<icon name="'apps'"></icon>
|
||||
{{playlistItem.title}}
|
||||
<icon name="'favorite'" type="'mono'" ng-show="playlistItem.isStarred"></icon>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-small pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)">
|
||||
<icon name="'plus'"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="tag in ctrl.filteredTags">
|
||||
<td>
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<icon name="'tag-alt'"></icon>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-small pull-right" ng-click="ctrl.addTagPlaylistItem(tag)">
|
||||
<icon name="'plus'"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.filteredDashboards.length > 0">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredDashboards">
|
||||
<td>
|
||||
<i class="gicon gicon-dashboard"></i>
|
||||
{{playlistItem.title}}
|
||||
<i class="fa fa-star" ng-show="playlistItem.isStarred"></i>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-small pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="tag in ctrl.filteredTags">
|
||||
<td>
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-small pull-right" ng-click="ctrl.addTagPlaylistItem(tag)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<a class="btn btn-primary" ng-show="ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create</a>
|
||||
<a class="btn btn-primary" ng-show="!ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
|
||||
<a class="btn-text" ng-click="ctrl.backToList()">Cancel</a>
|
||||
</div>
|
||||
<div class="gf-form-button-row">
|
||||
<a
|
||||
class="btn btn-primary"
|
||||
ng-show="ctrl.isNew"
|
||||
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
|
||||
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)"
|
||||
>Create</a
|
||||
>
|
||||
<a
|
||||
class="btn btn-primary"
|
||||
ng-show="!ctrl.isNew"
|
||||
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
|
||||
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)"
|
||||
>Save</a
|
||||
>
|
||||
<a class="btn-text" ng-click="ctrl.backToList()">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer />
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
<div class="playlist-search-field-wrapper">
|
||||
<span style="position: relative;">
|
||||
<input type="text" placeholder="Search dashboards by name" tabindex="1"
|
||||
ng-keydown="ctrl.keyDown($event)" ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.searchDashboards()" />
|
||||
<div class="playlist-search-switches">
|
||||
<i class="fa fa-filter"></i>
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.showStarred()" tabindex="2">
|
||||
<i class="fa fa-remove" ng-show="ctrl.query.starred"></i>
|
||||
starred
|
||||
</a> |
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.getTags()" tabindex="3">
|
||||
<i class="fa fa-remove" ng-show="ctrl.tagsMode"></i>
|
||||
tags
|
||||
</a>
|
||||
<span ng-if="ctrl.query.tag.length">
|
||||
|
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="ctrl.tagName" class="label label-tag">
|
||||
<i class="fa fa-remove"></i>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Find dashboards by name"
|
||||
tabindex="1"
|
||||
ng-keydown="ctrl.keyDown($event)"
|
||||
ng-model="ctrl.query.query"
|
||||
ng-model-options="{ debounce: 500 }"
|
||||
spellcheck="false"
|
||||
ng-change="ctrl.searchDashboards()"
|
||||
/>
|
||||
<div class="playlist-search-switches">
|
||||
<icon name="'filter'"></icon>
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.showStarred()" tabindex="2">
|
||||
<icon name="'times'" ng-show="ctrl.query.starred"></icon>
|
||||
starred
|
||||
</a>
|
||||
|
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.getTags()" tabindex="3">
|
||||
<icon name="'times'" ng-show="ctrl.tagsMode"></icon>
|
||||
tags
|
||||
</a>
|
||||
<span ng-if="ctrl.query.tag.length">
|
||||
|
|
||||
<span ng-repeat="tagName in ctrl.query.tag">
|
||||
<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="ctrl.tagName" class="label label-tag">
|
||||
<icon name="'times'"></icon>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<div ng-if="ctrl.playlists.length === 0">
|
||||
<empty-list-cta
|
||||
title="'There are no playlists created yet'"
|
||||
buttonIcon="'fa fa-plus'"
|
||||
buttonIcon="'plus'"
|
||||
buttonLink="'playlists/create'"
|
||||
buttonTitle="'Create Playlist'"
|
||||
proTip="'You can use playlists to cycle dashboards on TVs without user control'"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { StoreState } from 'app/types';
|
||||
|
||||
const navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
text: 'Sign Up',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent, ChangeEvent, MouseEvent } from 'react';
|
||||
import { Button, FormLabel, LegacyForms, Tooltip } from '@grafana/ui';
|
||||
import { Button, FormLabel, LegacyForms, Tooltip, Icon } from '@grafana/ui';
|
||||
const { Input } = LegacyForms;
|
||||
import { User } from 'app/types';
|
||||
import config from 'app/core/config';
|
||||
@@ -73,7 +73,7 @@ export class UserProfileEditForm extends PureComponent<Props, State> {
|
||||
/>
|
||||
{disableLoginForm && (
|
||||
<Tooltip content="Login Details Locked - managed in another system.">
|
||||
<i className="fa fa-lock gf-form-icon--right-absolute" />
|
||||
<Icon name="lock" className="gf-form-icon--right-absolute" />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
@@ -88,7 +88,7 @@ export class UserProfileEditForm extends PureComponent<Props, State> {
|
||||
/>
|
||||
{disableLoginForm && (
|
||||
<Tooltip content="Login Details Locked - managed in another system.">
|
||||
<i className="fa fa-lock gf-form-icon--right-absolute" />
|
||||
<Icon name="lock" className="gf-form-icon--right-absolute" />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useContext } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
// @ts-ignore
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { ThemeContext } from '@grafana/ui';
|
||||
import { ThemeContext, Icon } from '@grafana/ui';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { SearchQuery } from 'app/core/components/search/search';
|
||||
|
||||
@@ -56,7 +56,7 @@ export const SearchField: React.FunctionComponent<SearchFieldProps> = ({ query,
|
||||
{/* based on it GrafanaCtrl (L256) decides whether or not hide search */}
|
||||
<div className={`${styles.wrapper} search-field-wrapper`}>
|
||||
<div className={styles.icon}>
|
||||
<i className="fa fa-search" />
|
||||
<Icon name="search" />
|
||||
</div>
|
||||
|
||||
<input
|
||||
|
||||
@@ -54,7 +54,7 @@ export const SearchItem: FC<Props> = ({ item, editable, onToggleSelection, onTag
|
||||
>
|
||||
<SearchCheckbox editable={editable} checked={item.checked} onClick={toggleItem} />
|
||||
<a href={item.url} className={styles.link}>
|
||||
<Icon className={styles.icon} name="apps" />
|
||||
<Icon className={styles.icon} name="apps" size="lg" />
|
||||
<div className={styles.body} onClick={onItemClick}>
|
||||
<span>{item.title}</span>
|
||||
<span className={styles.folderTitle}>{item.folderTitle}</span>
|
||||
@@ -99,10 +99,7 @@ const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
top: -1px;
|
||||
`,
|
||||
icon: css`
|
||||
font-size: ${theme.typography.size.lg};
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 1px 2px 0 10px;
|
||||
margin-left: 10px;
|
||||
`,
|
||||
tags: css`
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -106,7 +106,7 @@ const SectionHeader: FC<SectionHeaderProps> = ({ section, onSectionClick, onTogg
|
||||
<Icon name="cog" />
|
||||
</a>
|
||||
)}
|
||||
<Icon name={section.expanded ? 'angle-down' : 'angle-right'} className={styles.toggle} />
|
||||
<Icon name={section.expanded ? 'angle-down' : 'angle-right'} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.wrapper} />
|
||||
@@ -139,7 +139,6 @@ const getSectionHeaderStyles = stylesFactory((theme: GrafanaTheme, selected = fa
|
||||
{ selected }
|
||||
),
|
||||
icon: css`
|
||||
padding: 5px 0;
|
||||
width: 43px;
|
||||
`,
|
||||
text: css`
|
||||
@@ -152,8 +151,5 @@ const getSectionHeaderStyles = stylesFactory((theme: GrafanaTheme, selected = fa
|
||||
opacity: 0;
|
||||
transition: opacity 150ms ease-in-out;
|
||||
`,
|
||||
toggle: css`
|
||||
padding: 5px;
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -46,10 +46,10 @@ export const SearchResultsFilter: FC<Props> = ({
|
||||
<Forms.Checkbox value={allChecked} onChange={onSelectAllChanged} />
|
||||
{showActions ? (
|
||||
<HorizontalGroup spacing="md">
|
||||
<Button disabled={!canMove} onClick={moveTo} icon="fa fa-exchange" variant="secondary">
|
||||
<Button disabled={!canMove} onClick={moveTo} icon="exchange-alt" variant="secondary">
|
||||
Move
|
||||
</Button>
|
||||
<Button disabled={!canDelete} onClick={deleteItem} icon="fa fa-trash" variant="destructive">
|
||||
<Button disabled={!canDelete} onClick={deleteItem} icon="trash-alt" variant="destructive">
|
||||
Delete
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { SlideDown } from 'app/core/components/Animations/SlideDown';
|
||||
import { LegacyForms, Tooltip } from '@grafana/ui';
|
||||
import { LegacyForms, Tooltip, Icon } from '@grafana/ui';
|
||||
const { Input } = LegacyForms;
|
||||
|
||||
import { TeamGroup } from '../../types';
|
||||
@@ -82,9 +82,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
|
||||
<div className="page-action-bar">
|
||||
<h3 className="page-sub-heading">External group sync</h3>
|
||||
<Tooltip placement="auto" content={headerTooltip}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
{groups.length > 0 && (
|
||||
@@ -123,7 +121,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
|
||||
{groups.length === 0 && !isAdding && (
|
||||
<EmptyListCTA
|
||||
onClick={this.onToggleAdding}
|
||||
buttonIcon="gicon gicon-team"
|
||||
buttonIcon="users-alt"
|
||||
title="There are no external groups to sync with"
|
||||
buttonTitle="Add Group"
|
||||
proTip={headerTooltip}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class TeamList extends PureComponent<Props, any> {
|
||||
return (
|
||||
<EmptyListCTA
|
||||
title="You haven't created any teams yet."
|
||||
buttonIcon="gicon gicon-team"
|
||||
buttonIcon="users-alt"
|
||||
buttonLink="org/teams/new"
|
||||
buttonTitle=" New team"
|
||||
proTip="Assign folder and dashboard permissions to teams instead of users to ease administration."
|
||||
|
||||
@@ -14,13 +14,10 @@ exports[`Render should render component 1`] = `
|
||||
content="Sync LDAP or OAuth groups with your Grafana teams."
|
||||
placement="auto"
|
||||
>
|
||||
<div
|
||||
className="page-sub-heading-icon"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</div>
|
||||
<Icon
|
||||
className="icon--has-hover page-sub-heading-icon"
|
||||
name="question-circle"
|
||||
/>
|
||||
</Component>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
@@ -73,7 +70,7 @@ exports[`Render should render component 1`] = `
|
||||
</div>
|
||||
</Component>
|
||||
<EmptyListCTA
|
||||
buttonIcon="gicon gicon-team"
|
||||
buttonIcon="users-alt"
|
||||
buttonTitle="Add Group"
|
||||
onClick={[Function]}
|
||||
proTip="Sync LDAP or OAuth groups with your Grafana teams."
|
||||
@@ -99,13 +96,10 @@ exports[`Render should render groups table 1`] = `
|
||||
content="Sync LDAP or OAuth groups with your Grafana teams."
|
||||
placement="auto"
|
||||
>
|
||||
<div
|
||||
className="page-sub-heading-icon"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</div>
|
||||
<Icon
|
||||
className="icon--has-hover page-sub-heading-icon"
|
||||
name="question-circle"
|
||||
/>
|
||||
</Component>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
|
||||
@@ -27,7 +27,7 @@ interface FormModel {
|
||||
|
||||
const navModel = {
|
||||
main: {
|
||||
icon: 'gicon gicon-branding',
|
||||
icon: 'grafana',
|
||||
text: 'Invite',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
||||
@@ -47,7 +47,7 @@ export class VariableEditorList extends PureComponent<Props> {
|
||||
<div>
|
||||
<EmptyListCTA
|
||||
title="There are no variables yet"
|
||||
buttonIcon="gicon gicon-variable"
|
||||
buttonIcon="calculator-alt"
|
||||
buttonTitle="Add variable"
|
||||
infoBox={{
|
||||
__html: ` <p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { getTagColorsFromName } from '@grafana/ui';
|
||||
import { getTagColorsFromName, Icon } from '@grafana/ui';
|
||||
import { e2e } from '@grafana/e2e';
|
||||
import { VariableTag } from '../../../templating/types';
|
||||
|
||||
@@ -30,12 +30,14 @@ export class VariableLink extends PureComponent<Props> {
|
||||
return (
|
||||
<span bs-tooltip="tag.valuesText" data-placement="bottom" key={`${tag.text}`}>
|
||||
<span className="label-tag" style={{ backgroundColor: color, borderColor }}>
|
||||
<i className="fa fa-tag"></i> {tag.text}
|
||||
|
||||
<Icon name="tag-alt" />
|
||||
{tag.text}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
<i className="fa fa-caret-down" style={{ fontSize: '12px' }}></i>
|
||||
<Icon name="angle-down" size="sm" />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { getTagColorsFromName, Tooltip } from '@grafana/ui';
|
||||
import { getTagColorsFromName, Tooltip, Icon } from '@grafana/ui';
|
||||
import { e2e } from '@grafana/e2e';
|
||||
import { VariableOption, VariableTag } from '../../../templating/types';
|
||||
|
||||
@@ -79,7 +79,9 @@ export class VariableOptions extends PureComponent<Props> {
|
||||
>
|
||||
<span className="fa fa-fw variable-option-icon"></span>
|
||||
<span className="label-tag" style={{ backgroundColor: color, borderColor }}>
|
||||
{tag.text} <i className="fa fa-tag"></i>
|
||||
{tag.text}
|
||||
<Icon name="tag-alt" />
|
||||
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
{{vm.linkText}}
|
||||
<span ng-repeat="tag in vm.selectedTags" bs-tooltip="tag.valuesText" data-placement="bottom">
|
||||
<span class="label-tag" tag-color-from-name="tag.text">
|
||||
<i class="fa fa-tag"></i> {{tag.text}}
|
||||
<icon name="'tag-alt'"></icon> {{tag.text}}
|
||||
</span>
|
||||
</span>
|
||||
<i class="fa fa-caret-down" style="font-size:12px"></i>
|
||||
<icon name="'angle-down'"></icon>
|
||||
</a>
|
||||
|
||||
<input
|
||||
@@ -63,7 +63,7 @@
|
||||
>
|
||||
<span class="fa fa-fw variable-option-icon"></span>
|
||||
<span class="label-tag" tag-color-from-name="tag.text"
|
||||
>{{tag.text}} <i class="fa fa-tag"></i> </span
|
||||
>{{tag.text}} <icon name="'tag-alt'"></icon> </span
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,7 @@ export const DataLink = (props: Props) => {
|
||||
<Button
|
||||
variant={'destructive'}
|
||||
title="Remove field"
|
||||
icon={'fa fa-times'}
|
||||
icon="times"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
onDelete();
|
||||
|
||||
@@ -67,7 +67,7 @@ export const DataLinks = (props: Props) => {
|
||||
className={css`
|
||||
margin-right: 10px;
|
||||
`}
|
||||
icon="fa fa-plus"
|
||||
icon="plus"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
const newDataLinks = [...(value || []), { field: '', url: '' }];
|
||||
|
||||
@@ -68,7 +68,7 @@ export const DerivedField = (props: Props) => {
|
||||
<Button
|
||||
variant="destructive"
|
||||
title="Remove field"
|
||||
icon={'fa fa-times'}
|
||||
icon="times"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
onDelete();
|
||||
|
||||
@@ -70,7 +70,7 @@ export const DerivedFields = (props: Props) => {
|
||||
className={css`
|
||||
margin-right: 10px;
|
||||
`}
|
||||
icon="fa fa-plus"
|
||||
icon="plus"
|
||||
onClick={event => {
|
||||
event.preventDefault();
|
||||
const newDerivedFields = [...(value || []), { name: '', matcherRegex: '' }];
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{dash.title}}
|
||||
</span>
|
||||
<span class="dashlist-star" ng-click="ctrl.starDashboard(dash, $event)">
|
||||
<i class="fa" ng-class="{'fa-star': dash.isStarred, 'fa-star-o': dash.isStarred === false}"></i>
|
||||
<icon name="dash.isStarred ? 'favorite':'star'" type="dash.isStarred ? 'mono':'default'"></icon>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.gicon--has-hover {
|
||||
.icon--has-hover {
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
.btn-small {
|
||||
@include button-size($btn-padding-y-sm, $space-sm, $font-size-sm, $border-radius-sm);
|
||||
height: $height-sm;
|
||||
svg {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated, only used by old plugins
|
||||
|
||||
@@ -41,7 +41,7 @@ $input-border: 1px solid $input-border-color;
|
||||
.gf-form-input-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -9px;
|
||||
margin-top: -8px;
|
||||
font-size: $font-size-lg;
|
||||
left: 10px;
|
||||
color: $input-color-placeholder;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user