mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #14766 from grafana/fix-toggle-button-group-corners
Fix toggle button group corners
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@torkelo/react-select": "2.1.1",
|
||||
"@types/react-test-renderer": "^16.0.3",
|
||||
"@types/react-transition-group": "^2.0.15",
|
||||
"classnames": "^2.2.5",
|
||||
"jquery": "^3.2.1",
|
||||
"lodash": "^4.17.10",
|
||||
|
||||
@@ -6,11 +6,11 @@ interface Props {
|
||||
root?: HTMLElement;
|
||||
}
|
||||
|
||||
export default class BodyPortal extends PureComponent<Props> {
|
||||
export class Portal extends PureComponent<Props> {
|
||||
node: HTMLElement = document.createElement('div');
|
||||
portalRoot: HTMLElement;
|
||||
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
const {
|
||||
className,
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Portal from 'app/core/components/Portal/Portal';
|
||||
import { Manager, Popper as ReactPopper, Reference } from 'react-popper';
|
||||
import * as PopperJS from 'popper.js';
|
||||
import { Manager, Popper as ReactPopper } from 'react-popper';
|
||||
import { Portal } from '@grafana/ui';
|
||||
import Transition from 'react-transition-group/Transition';
|
||||
|
||||
export enum Themes {
|
||||
@@ -13,45 +14,40 @@ const defaultTransitionStyles = {
|
||||
opacity: 0,
|
||||
};
|
||||
|
||||
const transitionStyles = {
|
||||
const transitionStyles: {[key: string]: object} = {
|
||||
exited: { opacity: 0 },
|
||||
entering: { opacity: 0 },
|
||||
entered: { opacity: 1 },
|
||||
exiting: { opacity: 0 },
|
||||
};
|
||||
|
||||
interface Props {
|
||||
interface Props extends React.DOMAttributes<HTMLDivElement> {
|
||||
renderContent: (content: any) => any;
|
||||
show: boolean;
|
||||
placement?: any;
|
||||
placement?: PopperJS.Placement;
|
||||
content: string | ((props: any) => JSX.Element);
|
||||
refClassName?: string;
|
||||
referenceElement: PopperJS.ReferenceObject;
|
||||
theme?: Themes;
|
||||
}
|
||||
|
||||
class Popper extends PureComponent<Props> {
|
||||
render() {
|
||||
const { children, renderContent, show, placement, refClassName, theme } = this.props;
|
||||
const { renderContent, show, placement, onMouseEnter, onMouseLeave, theme } = this.props;
|
||||
const { content } = this.props;
|
||||
|
||||
const popperBackgroundClassName = 'popper__background' + (theme ? ' ' + theme : '');
|
||||
|
||||
return (
|
||||
<Manager>
|
||||
<Reference>
|
||||
{({ ref }) => (
|
||||
<div className={`popper_ref ${refClassName || ''}`} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</Reference>
|
||||
<Transition in={show} timeout={100} mountOnEnter={true} unmountOnExit={true}>
|
||||
{transitionState => (
|
||||
<Portal>
|
||||
<ReactPopper placement={placement}>
|
||||
<ReactPopper placement={placement} referenceElement={this.props.referenceElement}>
|
||||
{({ ref, style, placement, arrowProps }) => {
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
ref={ref}
|
||||
style={{
|
||||
...style,
|
||||
@@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import * as PopperJS from 'popper.js';
|
||||
import { Themes } from './Popper';
|
||||
|
||||
type PopperContent = string | (() => JSX.Element);
|
||||
|
||||
export interface UsingPopperProps {
|
||||
show?: boolean;
|
||||
placement?: PopperJS.Placement;
|
||||
content: PopperContent;
|
||||
children: JSX.Element;
|
||||
renderContent?: (content: PopperContent) => JSX.Element;
|
||||
theme?: Themes;
|
||||
}
|
||||
|
||||
type PopperControllerRenderProp = (
|
||||
showPopper: () => void,
|
||||
hidePopper: () => void,
|
||||
popperProps: {
|
||||
show: boolean;
|
||||
placement: PopperJS.Placement;
|
||||
content: string | ((props: any) => JSX.Element);
|
||||
renderContent: (content: any) => any;
|
||||
theme?: Themes;
|
||||
}
|
||||
) => JSX.Element;
|
||||
|
||||
interface Props {
|
||||
placement?: PopperJS.Placement;
|
||||
content: PopperContent;
|
||||
className?: string;
|
||||
children: PopperControllerRenderProp;
|
||||
theme?: Themes;
|
||||
}
|
||||
|
||||
interface State {
|
||||
placement: PopperJS.Placement;
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
class PopperController extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
placement: this.props.placement || 'auto',
|
||||
show: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
if (nextProps.placement && nextProps.placement !== this.state.placement) {
|
||||
this.setState((prevState: State) => {
|
||||
return {
|
||||
...prevState,
|
||||
placement: nextProps.placement || 'auto',
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
showPopper = () => {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
show: true,
|
||||
}));
|
||||
};
|
||||
|
||||
hidePopper = () => {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
show: false,
|
||||
}));
|
||||
};
|
||||
|
||||
renderContent(content: PopperContent) {
|
||||
if (typeof content === 'function') {
|
||||
// If it's a function we assume it's a React component
|
||||
const ReactComponent = content;
|
||||
return <ReactComponent />;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, content, theme } = this.props;
|
||||
const { show, placement } = this.state;
|
||||
|
||||
return children(this.showPopper, this.hidePopper, {
|
||||
show,
|
||||
placement,
|
||||
content,
|
||||
renderContent: this.renderContent,
|
||||
theme,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default PopperController;
|
||||
@@ -1,13 +1,15 @@
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
import Tooltip from './Tooltip';
|
||||
import { Tooltip } from './Tooltip';
|
||||
|
||||
describe('Tooltip', () => {
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer
|
||||
.create(
|
||||
<Tooltip className="test-class" placement="auto" content="Tooltip text">
|
||||
<a href="http://www.grafana.com">Link with tooltip</a>
|
||||
<Tooltip placement="auto" content="Tooltip text">
|
||||
<a className="test-class" href="http://www.grafana.com">
|
||||
Link with tooltip
|
||||
</a>
|
||||
</Tooltip>
|
||||
)
|
||||
.toJSON();
|
||||
32
packages/grafana-ui/src/components/Tooltip/Tooltip.tsx
Normal file
32
packages/grafana-ui/src/components/Tooltip/Tooltip.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { createRef } from 'react';
|
||||
import * as PopperJS from 'popper.js';
|
||||
import Popper from './Popper';
|
||||
import PopperController, { UsingPopperProps } from './PopperController';
|
||||
|
||||
export const Tooltip = ({ children, renderContent, ...controllerProps }: UsingPopperProps) => {
|
||||
const tooltipTriggerRef = createRef<PopperJS.ReferenceObject>();
|
||||
|
||||
return (
|
||||
<PopperController {...controllerProps}>
|
||||
{(showPopper, hidePopper, popperProps) => {
|
||||
return (
|
||||
<>
|
||||
{tooltipTriggerRef.current && (
|
||||
<Popper
|
||||
{...popperProps}
|
||||
onMouseEnter={showPopper}
|
||||
onMouseLeave={hidePopper}
|
||||
referenceElement={tooltipTriggerRef.current}
|
||||
/>
|
||||
)}
|
||||
{React.cloneElement(children, {
|
||||
ref: tooltipTriggerRef,
|
||||
onMouseEnter: showPopper,
|
||||
onMouseLeave: hidePopper,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</PopperController>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Tooltip renders correctly 1`] = `
|
||||
<a
|
||||
className="test-class"
|
||||
href="http://www.grafana.com"
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
>
|
||||
Link with tooltip
|
||||
</a>
|
||||
`;
|
||||
@@ -1,2 +1,3 @@
|
||||
@import 'CustomScrollbar/CustomScrollbar';
|
||||
@import 'DeleteButton/DeleteButton';
|
||||
@import 'Tooltip/Tooltip';
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
export { DeleteButton } from './DeleteButton/DeleteButton';
|
||||
export { Tooltip } from './Tooltip/Tooltip';
|
||||
export { Portal } from './Portal/Portal';
|
||||
export { CustomScrollbar } from './CustomScrollbar/CustomScrollbar';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { SFC, ReactNode } from 'react';
|
||||
import Tooltip from '../Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
tooltip?: string;
|
||||
@@ -14,8 +14,10 @@ export const Label: SFC<Props> = props => {
|
||||
<span className={`gf-form-label width-${props.width ? props.width : '10'}`}>
|
||||
<span>{props.children}</span>
|
||||
{props.tooltip && (
|
||||
<Tooltip className="gf-form-help-icon--right-normal" placement="auto" content={props.tooltip}>
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
<Tooltip placement="auto" content={props.tooltip}>
|
||||
<div className="gf-form-help-icon--right-normal">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { SFC, ReactNode, PureComponent } from 'react';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
|
||||
interface ToggleButtonGroupProps {
|
||||
label?: string;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
import Popover from './Popover';
|
||||
|
||||
describe('Popover', () => {
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer
|
||||
.create(
|
||||
<Popover className="test-class" placement="auto" content="Popover text">
|
||||
<button>Button with Popover</button>
|
||||
</Popover>
|
||||
)
|
||||
.toJSON();
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,19 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Popper from './Popper';
|
||||
import withPopper, { UsingPopperProps } from './withPopper';
|
||||
|
||||
class Popover extends PureComponent<UsingPopperProps> {
|
||||
render() {
|
||||
const { children, hidePopper, showPopper, className, ...restProps } = this.props;
|
||||
|
||||
const togglePopper = restProps.show ? hidePopper : showPopper;
|
||||
|
||||
return (
|
||||
<div className={`popper__manager ${className}`} onClick={togglePopper}>
|
||||
<Popper {...restProps}>{children}</Popper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withPopper(Popover);
|
||||
@@ -1,17 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Popper from './Popper';
|
||||
import withPopper, { UsingPopperProps } from './withPopper';
|
||||
|
||||
class Tooltip extends PureComponent<UsingPopperProps> {
|
||||
render() {
|
||||
const { children, hidePopper, showPopper, className, ...restProps } = this.props;
|
||||
|
||||
return (
|
||||
<div className={`popper__manager ${className}`} onMouseEnter={showPopper} onMouseLeave={hidePopper}>
|
||||
<Popper {...restProps}>{children}</Popper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withPopper(Tooltip);
|
||||
@@ -1,16 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Popover renders correctly 1`] = `
|
||||
<div
|
||||
className="popper__manager test-class"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<div
|
||||
className="popper_ref "
|
||||
>
|
||||
<button>
|
||||
Button with Popover
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,19 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Tooltip renders correctly 1`] = `
|
||||
<div
|
||||
className="popper__manager test-class"
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
>
|
||||
<div
|
||||
className="popper_ref "
|
||||
>
|
||||
<a
|
||||
href="http://www.grafana.com"
|
||||
>
|
||||
Link with tooltip
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,89 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Themes } from './Popper';
|
||||
export interface UsingPopperProps {
|
||||
showPopper: (prevState: object) => void;
|
||||
hidePopper: (prevState: object) => void;
|
||||
renderContent: (content: any) => any;
|
||||
show: boolean;
|
||||
placement?: string;
|
||||
content: string | ((props: any) => JSX.Element);
|
||||
className?: string;
|
||||
refClassName?: string;
|
||||
theme?: Themes;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
placement?: string;
|
||||
className?: string;
|
||||
refClassName?: string;
|
||||
content: string | ((props: any) => JSX.Element);
|
||||
theme?: Themes;
|
||||
}
|
||||
|
||||
interface State {
|
||||
placement: string;
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
export default function withPopper(WrappedComponent) {
|
||||
return class extends React.Component<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.setState = this.setState.bind(this);
|
||||
this.state = {
|
||||
placement: this.props.placement || 'auto',
|
||||
show: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.placement && nextProps.placement !== this.state.placement) {
|
||||
this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
placement: nextProps.placement,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
showPopper = () => {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
show: true,
|
||||
}));
|
||||
};
|
||||
|
||||
hidePopper = () => {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
show: false,
|
||||
}));
|
||||
};
|
||||
|
||||
renderContent(content) {
|
||||
if (typeof content === 'function') {
|
||||
// If it's a function we assume it's a React component
|
||||
const ReactComponent = content;
|
||||
return <ReactComponent />;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { show, placement } = this.state;
|
||||
const className = this.props.className || '';
|
||||
return (
|
||||
<WrappedComponent
|
||||
{...this.props}
|
||||
showPopper={this.showPopper}
|
||||
hidePopper={this.hidePopper}
|
||||
renderContent={this.renderContent}
|
||||
show={show}
|
||||
placement={placement}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Library
|
||||
import React, { Component } from 'react';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import { Themes } from '@grafana/ui/src/components/Tooltip/Popper';
|
||||
|
||||
import ErrorBoundary from 'app/core/components/ErrorBoundary/ErrorBoundary';
|
||||
|
||||
// Services
|
||||
@@ -12,7 +14,6 @@ import kbn from 'app/core/utils/kbn';
|
||||
// Types
|
||||
import { DataQueryOptions, DataQueryResponse } from 'app/types';
|
||||
import { TimeRange, TimeSeries, LoadingState } from '@grafana/ui';
|
||||
import { Themes } from 'app/core/components/Tooltip/Popper';
|
||||
|
||||
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
|
||||
|
||||
@@ -144,10 +145,10 @@ export class DataPanel extends Component<Props, State> {
|
||||
this.setState({
|
||||
loading: LoadingState.Error,
|
||||
isFirstLoad: false,
|
||||
errorMessage: errorMessage
|
||||
errorMessage: errorMessage,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { queries } = this.props;
|
||||
@@ -171,7 +172,7 @@ export class DataPanel extends Component<Props, State> {
|
||||
<>
|
||||
{this.renderLoadingStates()}
|
||||
<ErrorBoundary>
|
||||
{({error, errorInfo}) => {
|
||||
{({ error, errorInfo }) => {
|
||||
if (errorInfo) {
|
||||
this.onError(error.message || DEFAULT_PLUGIN_ERROR);
|
||||
return null;
|
||||
@@ -200,15 +201,11 @@ export class DataPanel extends Component<Props, State> {
|
||||
);
|
||||
} else if (loading === LoadingState.Error) {
|
||||
return (
|
||||
<Tooltip
|
||||
content={errorMessage}
|
||||
className="popper__manager--block"
|
||||
refClassName={`panel-info-corner panel-info-corner--error`}
|
||||
placement="bottom-start"
|
||||
theme={Themes.Error}
|
||||
>
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
<Tooltip content={errorMessage} placement="bottom-start" theme={Themes.Error}>
|
||||
<div className="panel-info-corner panel-info-corner--error">
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { SFC } from 'react';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
|
||||
@@ -15,7 +15,7 @@ import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { PanelPlugin } from 'app/types/plugins';
|
||||
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
|
||||
interface PanelEditorProps {
|
||||
panel: PanelModel;
|
||||
@@ -138,7 +138,7 @@ function TabItem({ tab, activeTab, onClick }: TabItemParams) {
|
||||
return (
|
||||
<div className="panel-editor-tabs__item" onClick={() => onClick(tab)}>
|
||||
<a className={tabClasses}>
|
||||
<Tooltip content={`${tab.text}`} className="popper__manager--block" placement="auto">
|
||||
<Tooltip content={`${tab.text}`} placement="auto">
|
||||
<i className={`gicon gicon-${tab.id}${activeTab === tab.id ? '-active' : ''}`} />
|
||||
</Tooltip>
|
||||
</a>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { Component } from 'react';
|
||||
import Remarkable from 'remarkable';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import { PanelModel } from 'app/features/dashboard/panel_model';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import templateSrv from 'app/features/templating/template_srv';
|
||||
import { LinkSrv } from 'app/features/dashboard/panellinks/link_srv';
|
||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/time_srv';
|
||||
import Remarkable from 'remarkable';
|
||||
|
||||
enum InfoModes {
|
||||
Error = 'Error',
|
||||
@@ -78,12 +78,14 @@ export class PanelHeaderCorner extends Component<Props> {
|
||||
{infoMode === InfoModes.Info || infoMode === InfoModes.Links ? (
|
||||
<Tooltip
|
||||
content={this.getInfoContent}
|
||||
className="popper__manager--block"
|
||||
refClassName={`panel-info-corner panel-info-corner--${infoMode.toLowerCase()}`}
|
||||
placement="bottom-start"
|
||||
>
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
<div
|
||||
className={`panel-info-corner panel-info-corner--${infoMode.toLowerCase()}`}
|
||||
>
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } 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';
|
||||
@@ -70,8 +70,10 @@ export class DashboardPermissions extends PureComponent<Props, State> {
|
||||
<div className="dashboard-settings__header">
|
||||
<div className="page-action-bar">
|
||||
<h3 className="d-inline-block">Permissions</h3>
|
||||
<Tooltip className="page-sub-heading-icon" placement="auto" content={PermissionsInfo}>
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
<Tooltip placement="auto" content={PermissionsInfo}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { connect } from 'react-redux';
|
||||
import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import SlideDown from 'app/core/components/Animations/SlideDown';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { NavModel, StoreState, FolderState } from 'app/types';
|
||||
@@ -84,8 +84,10 @@ export class FolderPermissions extends PureComponent<Props, State> {
|
||||
<div className="page-container page-body">
|
||||
<div className="page-action-bar">
|
||||
<h3 className="page-sub-heading">Folder Permissions</h3>
|
||||
<Tooltip className="page-sub-heading-icon" placement="auto" content={PermissionsInfo}>
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
<Tooltip placement="auto" content={PermissionsInfo}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import SlideDown from 'app/core/components/Animations/SlideDown';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import { Tooltip } from '@grafana/ui';
|
||||
import { TeamGroup } from '../../types';
|
||||
import { addTeamGroup, loadTeamGroups, removeTeamGroup } from './state/actions';
|
||||
import { getTeamGroups } from './state/selectors';
|
||||
@@ -77,8 +77,10 @@ export class TeamGroupSync extends PureComponent<Props, State> {
|
||||
<div>
|
||||
<div className="page-action-bar">
|
||||
<h3 className="page-sub-heading">External group sync</h3>
|
||||
<Tooltip className="page-sub-heading-icon" placement="auto" content={headerTooltip}>
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
<Tooltip placement="auto" content={headerTooltip}>
|
||||
<div className="page-sub-heading-icon">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="page-action-bar__spacer" />
|
||||
{groups.length > 0 && (
|
||||
|
||||
@@ -60,6 +60,7 @@ export class TeamSettings extends React.Component<Props, State> {
|
||||
onChange={this.onChangeName}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="gf-form max-width-30">
|
||||
<Label tooltip="This is optional and is primarily used to set the team profile avatar (via gravatar service)">
|
||||
Email
|
||||
|
||||
@@ -10,15 +10,18 @@ exports[`Render should render component 1`] = `
|
||||
>
|
||||
External group sync
|
||||
</h3>
|
||||
<class_1
|
||||
className="page-sub-heading-icon"
|
||||
<Component
|
||||
content="Sync LDAP or OAuth groups with your Grafana teams."
|
||||
placement="auto"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</class_1>
|
||||
<div
|
||||
className="page-sub-heading-icon"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</div>
|
||||
</Component>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
@@ -116,15 +119,18 @@ exports[`Render should render groups table 1`] = `
|
||||
>
|
||||
External group sync
|
||||
</h3>
|
||||
<class_1
|
||||
className="page-sub-heading-icon"
|
||||
<Component
|
||||
content="Sync LDAP or OAuth groups with your Grafana teams."
|
||||
placement="auto"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</class_1>
|
||||
<div
|
||||
className="page-sub-heading-icon"
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-question gicon--has-hover"
|
||||
/>
|
||||
</div>
|
||||
</Component>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
@import 'components/page_header';
|
||||
@import 'components/dashboard_settings';
|
||||
@import 'components/empty_list_cta';
|
||||
@import 'components/popper';
|
||||
@import 'components/form_select_box';
|
||||
@import 'components/panel_editor';
|
||||
@import 'components/toolbar';
|
||||
|
||||
@@ -1098,10 +1098,10 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@*":
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.14.tgz#afd0cd785a97f070b55765e9f9d76ff568269001"
|
||||
integrity sha512-pa7qB0/mkhwWMBFoXhX8BcntK8G4eQl4sIfSrJCxnivTYRQWjOWf2ClR9bWdm0EUFBDHzMbKYS+QYfDtBzkY4w==
|
||||
"@types/react-transition-group@^2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.15.tgz#e5ee3fe558832e141cc6041bdd54caea7b787af8"
|
||||
integrity sha512-S0QnNzbHoWXDbKBl/xk5dxA4FT+BNlBcI3hku991cl8Cz3ytOkUMcCRtzdX11eb86E131bSsQqy5WrPCdJYblw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user