mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
UI: ConfirmButton component (#20993)
* UI: ConfirmButton component
* UI: add link button variant
* UI: add ConfirmButton story with delete option
* Chore: use ConfirmButton instead of DeleteButton
* UI: remove DeleteButton
* UI: rename confirmButtonVariant to confirmVariant
* UI: use Form.Button in ConfirmButton
* Chore: use sm ConfirmButton size after changing defaults
* Revert "UI: add link button variant"
This reverts commit 4372350daa
.
* Chore: add 'link' variant type to the Button
* UI: DeleteButton component on top of ConfirmButton
* Chore: use DeleteButton instead of ConfirmButton
* Chore: DeleteButton, use md size by default
* Chore: update test snapshots
This commit is contained in:
parent
4dba02dd20
commit
fd2131c1e3
@ -1,6 +1,6 @@
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'inverse' | 'transparent' | 'destructive';
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'inverse' | 'transparent' | 'destructive' | 'link';
|
||||
|
||||
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
|
||||
|
||||
|
@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { text, boolean, select } from '@storybook/addon-knobs';
|
||||
import { ConfirmButton } from './ConfirmButton';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Button } from '../Button/Button';
|
||||
|
||||
const getKnobs = () => {
|
||||
return {
|
||||
buttonText: text('Button text', 'Edit'),
|
||||
confirmText: text('Confirm text', 'Save'),
|
||||
size: select('Size', ['sm', 'md', 'lg'], 'md'),
|
||||
confirmVariant: select(
|
||||
'Confirm variant',
|
||||
{
|
||||
primary: 'primary',
|
||||
secondary: 'secondary',
|
||||
danger: 'danger',
|
||||
inverse: 'inverse',
|
||||
transparent: 'transparent',
|
||||
},
|
||||
'primary'
|
||||
),
|
||||
disabled: boolean('Disabled', false),
|
||||
};
|
||||
};
|
||||
|
||||
storiesOf('UI/ConfirmButton', module)
|
||||
.addDecorator(withCenteredStory)
|
||||
.add('default', () => {
|
||||
const { size, buttonText, confirmText, confirmVariant, disabled } = getKnobs();
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<ConfirmButton
|
||||
size={size}
|
||||
confirmText={confirmText}
|
||||
disabled={disabled}
|
||||
confirmVariant={confirmVariant}
|
||||
onConfirm={() => {
|
||||
action('Saved')('save!');
|
||||
}}
|
||||
>
|
||||
{buttonText}
|
||||
</ConfirmButton>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
})
|
||||
.add('with custom button', () => {
|
||||
const { buttonText, confirmText, confirmVariant, disabled, size } = getKnobs();
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<ConfirmButton
|
||||
size={size}
|
||||
confirmText={confirmText}
|
||||
disabled={disabled}
|
||||
confirmVariant={confirmVariant}
|
||||
onConfirm={() => {
|
||||
action('Saved')('save!');
|
||||
}}
|
||||
>
|
||||
<Button size={size} variant="secondary" icon="fa fa-pencil">
|
||||
{buttonText}
|
||||
</Button>
|
||||
</ConfirmButton>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { ConfirmButton } from './ConfirmButton';
|
||||
import { mount, ShallowWrapper } from 'enzyme';
|
||||
import { Button } from '../Button/Button';
|
||||
|
||||
describe('ConfirmButton', () => {
|
||||
let wrapper: any;
|
||||
let deleted: any;
|
||||
|
||||
beforeAll(() => {
|
||||
deleted = false;
|
||||
|
||||
function deleteItem() {
|
||||
deleted = true;
|
||||
}
|
||||
|
||||
wrapper = mount(
|
||||
<ConfirmButton confirmText="Confirm delete" onConfirm={() => deleteItem()}>
|
||||
Delete
|
||||
</ConfirmButton>
|
||||
);
|
||||
});
|
||||
|
||||
it('should show confirm delete when clicked', () => {
|
||||
expect(deleted).toBe(false);
|
||||
wrapper
|
||||
.find(Button)
|
||||
.findWhere((n: ShallowWrapper) => {
|
||||
return n.text() === 'Confirm delete' && n.type() === Button;
|
||||
})
|
||||
.simulate('click');
|
||||
expect(deleted).toBe(true);
|
||||
});
|
||||
});
|
@ -0,0 +1,160 @@
|
||||
import React, { PureComponent, SyntheticEvent } from 'react';
|
||||
import { cx, css } from 'emotion';
|
||||
import { stylesFactory, withTheme } from '../../themes';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { Themeable } from '../../types';
|
||||
import { Button } from '../Button/Button';
|
||||
import Forms from '../Forms';
|
||||
import { ButtonVariant, ButtonSize } from '../Button/types';
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
buttonContainer: css`
|
||||
direction: rtl;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`,
|
||||
buttonDisabled: css`
|
||||
text-decoration: none;
|
||||
color: ${theme.colors.text};
|
||||
opacity: 0.65;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
`,
|
||||
buttonShow: css`
|
||||
opacity: 1;
|
||||
transition: opacity 0.1s ease;
|
||||
z-index: 2;
|
||||
`,
|
||||
buttonHide: css`
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s ease;
|
||||
z-index: 0;
|
||||
`,
|
||||
confirmButtonContainer: css`
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
`,
|
||||
confirmButton: css`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
`,
|
||||
confirmButtonShow: css`
|
||||
opacity: 1;
|
||||
transition: opacity 0.08s ease-out, transform 0.1s ease-out;
|
||||
transform: translateX(0);
|
||||
`,
|
||||
confirmButtonHide: css`
|
||||
opacity: 0;
|
||||
transition: opacity 0.12s ease-in, transform 0.14s ease-in;
|
||||
transform: translateX(100px);
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
interface Props extends Themeable {
|
||||
className?: string;
|
||||
size?: ButtonSize;
|
||||
confirmText?: string;
|
||||
disabled?: boolean;
|
||||
confirmVariant?: ButtonVariant;
|
||||
|
||||
onConfirm(): void;
|
||||
onClick?(): void;
|
||||
onCancel?(): void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
showConfirm: boolean;
|
||||
}
|
||||
|
||||
class UnThemedConfirmButton extends PureComponent<Props, State> {
|
||||
static defaultProps: Partial<Props> = {
|
||||
size: 'md',
|
||||
confirmText: 'Save',
|
||||
disabled: false,
|
||||
confirmVariant: 'primary',
|
||||
};
|
||||
|
||||
state: State = {
|
||||
showConfirm: false,
|
||||
};
|
||||
|
||||
onClickButton = (event: SyntheticEvent) => {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
this.setState({
|
||||
showConfirm: true,
|
||||
});
|
||||
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
}
|
||||
};
|
||||
|
||||
onClickCancel = (event: SyntheticEvent) => {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
this.setState({
|
||||
showConfirm: false,
|
||||
});
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
theme,
|
||||
className,
|
||||
size,
|
||||
disabled,
|
||||
confirmText,
|
||||
confirmVariant: confirmButtonVariant,
|
||||
onConfirm,
|
||||
children,
|
||||
} = this.props;
|
||||
const styles = getStyles(theme);
|
||||
const buttonClass = cx(
|
||||
className,
|
||||
this.state.showConfirm ? styles.buttonHide : styles.buttonShow,
|
||||
disabled && styles.buttonDisabled
|
||||
);
|
||||
const confirmButtonClass = cx(
|
||||
styles.confirmButton,
|
||||
this.state.showConfirm ? styles.confirmButtonShow : styles.confirmButtonHide
|
||||
);
|
||||
const onClick = disabled ? () => {} : this.onClickButton;
|
||||
|
||||
return (
|
||||
<span className={styles.buttonContainer}>
|
||||
{typeof children === 'string' ? (
|
||||
<Forms.Button className={buttonClass} size={size} variant="link" onClick={onClick}>
|
||||
{children}
|
||||
</Forms.Button>
|
||||
) : (
|
||||
<span className={buttonClass} onClick={onClick}>
|
||||
{children}
|
||||
</span>
|
||||
)}
|
||||
<span className={styles.confirmButtonContainer}>
|
||||
<span className={confirmButtonClass}>
|
||||
<Button size={size} variant="transparent" onClick={this.onClickCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size={size} variant={confirmButtonVariant} onClick={onConfirm}>
|
||||
{confirmText}
|
||||
</Button>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ConfirmButton = withTheme(UnThemedConfirmButton);
|
||||
ConfirmButton.displayName = 'ConfirmButton';
|
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { boolean, select } from '@storybook/addon-knobs';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { DeleteButton } from './DeleteButton';
|
||||
|
||||
const getKnobs = () => {
|
||||
return {
|
||||
size: select('Size', ['sm', 'md', 'lg'], 'md'),
|
||||
disabled: boolean('Disabled', false),
|
||||
};
|
||||
};
|
||||
|
||||
storiesOf('UI/ConfirmButton', module)
|
||||
.addDecorator(withCenteredStory)
|
||||
.add('delete button', () => {
|
||||
const { disabled, size } = getKnobs();
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<DeleteButton
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
onConfirm={() => {
|
||||
action('Deleted')('delete!');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
import React, { FC } from 'react';
|
||||
import { ConfirmButton } from './ConfirmButton';
|
||||
import { Button } from '../Button/Button';
|
||||
import { ButtonSize } from '../Button/types';
|
||||
|
||||
interface Props {
|
||||
size?: ButtonSize;
|
||||
disabled?: boolean;
|
||||
onConfirm(): void;
|
||||
}
|
||||
|
||||
export const DeleteButton: FC<Props> = ({ size, disabled, onConfirm }) => {
|
||||
return (
|
||||
<ConfirmButton
|
||||
confirmText="Delete"
|
||||
confirmVariant="danger"
|
||||
size={size || 'md'}
|
||||
disabled={disabled}
|
||||
onConfirm={onConfirm}
|
||||
>
|
||||
<Button variant="danger" icon="fa fa-remove" size={size || 'sm'} />
|
||||
</ConfirmButton>
|
||||
);
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { DeleteButton } from './DeleteButton';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
storiesOf('UI/DeleteButton', module)
|
||||
.addDecorator(withCenteredStory)
|
||||
.add('default', () => {
|
||||
return (
|
||||
<DeleteButton
|
||||
onConfirm={() => {
|
||||
action('Delete Confirmed')('delete!');
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
import React from 'react';
|
||||
import { DeleteButton } from './DeleteButton';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('DeleteButton', () => {
|
||||
let wrapper: any;
|
||||
let deleted: any;
|
||||
|
||||
beforeAll(() => {
|
||||
deleted = false;
|
||||
|
||||
function deleteItem() {
|
||||
deleted = true;
|
||||
}
|
||||
|
||||
wrapper = shallow(<DeleteButton onConfirm={() => deleteItem()} />);
|
||||
});
|
||||
|
||||
it('should show confirm delete when clicked', () => {
|
||||
expect(wrapper.state().showConfirm).toBe(false);
|
||||
wrapper.find('.delete-button').simulate('click');
|
||||
expect(wrapper.state().showConfirm).toBe(true);
|
||||
});
|
||||
|
||||
it('should hide confirm delete when clicked', () => {
|
||||
wrapper.find('.delete-button').simulate('click');
|
||||
expect(wrapper.state().showConfirm).toBe(true);
|
||||
wrapper
|
||||
.find('.confirm-delete')
|
||||
.find('.btn')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(wrapper.state().showConfirm).toBe(false);
|
||||
});
|
||||
|
||||
it('should show confirm delete when clicked', () => {
|
||||
expect(deleted).toBe(false);
|
||||
wrapper
|
||||
.find('.confirm-delete')
|
||||
.find('.btn')
|
||||
.at(1)
|
||||
.simulate('click');
|
||||
expect(deleted).toBe(true);
|
||||
});
|
||||
});
|
@ -1,64 +0,0 @@
|
||||
import React, { PureComponent, SyntheticEvent } from 'react';
|
||||
|
||||
interface Props {
|
||||
onConfirm(): void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
interface State {
|
||||
showConfirm: boolean;
|
||||
}
|
||||
|
||||
export class DeleteButton extends PureComponent<Props, State> {
|
||||
state: State = {
|
||||
showConfirm: false,
|
||||
};
|
||||
|
||||
onClickDelete = (event: SyntheticEvent) => {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
this.setState({
|
||||
showConfirm: true,
|
||||
});
|
||||
};
|
||||
|
||||
onClickCancel = (event: SyntheticEvent) => {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
this.setState({
|
||||
showConfirm: false,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { onConfirm, disabled } = this.props;
|
||||
const showConfirmClass = this.state.showConfirm ? 'show' : 'hide';
|
||||
const showDeleteButtonClass = this.state.showConfirm ? 'hide' : 'show';
|
||||
const disabledClass = disabled ? 'disabled btn-inverse' : '';
|
||||
const onClick = disabled ? () => {} : this.onClickDelete;
|
||||
|
||||
return (
|
||||
<span className="delete-button-container">
|
||||
<a
|
||||
className={`delete-button ${showDeleteButtonClass} btn btn-danger btn-small ${disabledClass}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
<i className="fa fa-remove" />
|
||||
</a>
|
||||
<span className="confirm-delete-container">
|
||||
<span className={`confirm-delete ${showConfirmClass}`}>
|
||||
<a className="btn btn-small" onClick={this.onClickCancel}>
|
||||
Cancel
|
||||
</a>
|
||||
<a className="btn btn-danger btn-small" onClick={onConfirm}>
|
||||
Confirm Delete
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// sets a fixed width so that the rest of the table
|
||||
// isn't affected by the animation
|
||||
.delete-button-container {
|
||||
width: 24px;
|
||||
direction: rtl;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
//this container is used to make sure confirm-delete isn't
|
||||
//shown outside of table
|
||||
.confirm-delete-container {
|
||||
overflow: hidden;
|
||||
width: 145px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
position: absolute;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
transition: opacity 0.1s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&.hide {
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s ease;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-delete {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
transition: opacity 0.08s ease-out, transform 0.1s ease-out;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
&.hide {
|
||||
opacity: 0;
|
||||
transition: opacity 0.12s ease-in, transform 0.14s ease-in;
|
||||
transform: translateX(100px);
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ export default {
|
||||
},
|
||||
};
|
||||
|
||||
const variants = ['primary', 'secondary', 'destructive'];
|
||||
const variants = ['primary', 'secondary', 'destructive', 'link'];
|
||||
|
||||
const sizes = ['sm', 'md', 'lg'];
|
||||
|
||||
|
@ -52,6 +52,19 @@ const getPropertiesForVariant = (theme: GrafanaTheme, variant: ButtonVariant) =>
|
||||
background: buttonVariantStyles(theme.colors.redBase, theme.colors.redShade, theme.colors.white),
|
||||
};
|
||||
|
||||
case 'link':
|
||||
return {
|
||||
borderColor: 'transparent',
|
||||
background: buttonVariantStyles('transparent', 'transparent', theme.colors.linkExternal),
|
||||
variantStyles: css`
|
||||
text-decoration: underline;
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
case 'primary':
|
||||
default:
|
||||
return {
|
||||
@ -65,7 +78,7 @@ const getPropertiesForVariant = (theme: GrafanaTheme, variant: ButtonVariant) =>
|
||||
type StyleProps = Omit<StyleDeps, 'variant'> & { variant: ButtonVariant };
|
||||
export const getButtonStyles = stylesFactory(({ theme, size, variant }: StyleProps) => {
|
||||
const { padding, fontSize, height } = getPropertiesForButtonSize(theme, size);
|
||||
const { background, borderColor } = getPropertiesForVariant(theme, variant);
|
||||
const { background, borderColor, variantStyles } = getPropertiesForVariant(theme, variant);
|
||||
|
||||
return {
|
||||
button: cx(
|
||||
@ -93,7 +106,10 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant }: StylePro
|
||||
box-shadow: none;
|
||||
}
|
||||
`,
|
||||
getFocusStyle(theme)
|
||||
getFocusStyle(theme),
|
||||
css`
|
||||
${variantStyles}
|
||||
`
|
||||
),
|
||||
iconWrap: css`
|
||||
label: button-icon-wrap;
|
||||
@ -103,8 +119,8 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant }: StylePro
|
||||
};
|
||||
});
|
||||
|
||||
// These are different from the standard Button where there are 5 variants.
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'destructive';
|
||||
// These are different from the standard Button where there are more variants.
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link';
|
||||
|
||||
// These also needs to be different because the ButtonVariant is different
|
||||
type CommonProps = {
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { getFormStyles } from './getFormStyles';
|
||||
import { Label } from './Label';
|
||||
import { Input } from './Input/Input';
|
||||
import { Button } from './Button';
|
||||
|
||||
const Forms = {
|
||||
getFormStyles,
|
||||
Label: Label,
|
||||
Input: Input,
|
||||
Button: Button,
|
||||
};
|
||||
|
||||
export default Forms;
|
||||
|
@ -2,7 +2,6 @@
|
||||
@import 'Cascader/Cascader';
|
||||
@import 'ColorPicker/ColorPicker';
|
||||
@import 'CustomScrollbar/CustomScrollbar';
|
||||
@import 'DeleteButton/DeleteButton';
|
||||
@import 'Drawer/Drawer';
|
||||
@import 'EmptySearchResult/EmptySearchResult';
|
||||
@import 'FormField/FormField';
|
||||
|
@ -1,4 +1,5 @@
|
||||
export { DeleteButton } from './DeleteButton/DeleteButton';
|
||||
export { ConfirmButton } from './ConfirmButton/ConfirmButton';
|
||||
export { DeleteButton } from './ConfirmButton/DeleteButton';
|
||||
export { Tooltip, PopoverContent } from './Tooltip/Tooltip';
|
||||
export { PopoverController } from './Tooltip/PopoverController';
|
||||
export { Popover } from './Tooltip/Popover';
|
||||
|
@ -12,7 +12,7 @@ import ApiKeysAddedModal from './ApiKeysAddedModal';
|
||||
import config from 'app/core/config';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { DeleteButton, EventsWithValidation, FormLabel, Input, Switch, ValidationEvents } from '@grafana/ui';
|
||||
import { EventsWithValidation, FormLabel, Input, Switch, ValidationEvents, DeleteButton } from '@grafana/ui';
|
||||
import { NavModel, dateTime, isDateTime } from '@grafana/data';
|
||||
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
||||
import { store } from 'app/store/store';
|
||||
@ -287,7 +287,7 @@ export class ApiKeysPage extends PureComponent<Props, any> {
|
||||
<td>{key.role}</td>
|
||||
<td>{this.formatDate(key.expiration)}</td>
|
||||
<td>
|
||||
<DeleteButton onConfirm={() => this.onDeleteApiKey(key)} />
|
||||
<DeleteButton size="sm" onConfirm={() => this.onDeleteApiKey(key)} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -66,7 +66,7 @@ export class TeamList extends PureComponent<Props, any> {
|
||||
<a href={teamUrl}>{team.memberCount}</a>
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<DeleteButton onConfirm={() => this.deleteTeam(team)} disabled={!canDelete} />
|
||||
<DeleteButton size="sm" disabled={!canDelete} onConfirm={() => this.deleteTeam(team)} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { DeleteButton, Select } from '@grafana/ui';
|
||||
import { Select, DeleteButton } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
|
||||
import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types';
|
||||
@ -86,7 +86,7 @@ export class TeamMemberRow extends PureComponent<Props> {
|
||||
{this.renderPermissions(member)}
|
||||
{syncEnabled && this.renderLabels(member.labels)}
|
||||
<td className="text-right">
|
||||
<DeleteButton onConfirm={() => this.onRemoveMember(member)} disabled={!signedInUserIsTeamAdmin} />
|
||||
<DeleteButton size="sm" disabled={!signedInUserIsTeamAdmin} onConfirm={() => this.onRemoveMember(member)} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -132,9 +132,10 @@ exports[`Render should render teams table 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -183,9 +184,10 @@ exports[`Render should render teams table 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -234,9 +236,10 @@ exports[`Render should render teams table 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -285,9 +288,10 @@ exports[`Render should render teams table 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -336,9 +340,10 @@ exports[`Render should render teams table 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -462,9 +467,10 @@ exports[`Render when feature toggle editorsCanAdmin is turned on and signedin us
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={true}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -588,9 +594,10 @@ exports[`Render when feature toggle editorsCanAdmin is turned on and signedin us
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={true}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -48,9 +48,10 @@ exports[`Render should render team members when sync enabled 1`] = `
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={true}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -137,9 +138,10 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -226,9 +228,10 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@ -273,9 +276,10 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render s
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
<Component
|
||||
disabled={true}
|
||||
onConfirm={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
Loading…
Reference in New Issue
Block a user