feat(ui/buttons): introduce Add and Delete buttons [EE-6296] (#10585)

pull/10631/head
Chaim Lev-Ari 2023-11-14 12:36:15 +02:00 committed by GitHub
parent 66635ba6b1
commit 1f2f4525e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 47 deletions

View File

@ -1,3 +0,0 @@
.add-button {
border: none;
}

View File

@ -1,20 +1,21 @@
import { Meta, Story } from '@storybook/react';
import { AddButton, Props } from './AddButton';
import { AddButton } from './AddButton';
export default {
component: AddButton,
title: 'Components/Buttons/AddButton',
} as Meta;
function Template({ label, onClick }: JSX.IntrinsicAttributes & Props) {
return <AddButton label={label} onClick={onClick} />;
type Args = {
label: string;
};
function Template({ label }: Args) {
return <AddButton>{label}</AddButton>;
}
export const Primary: Story<Props> = Template.bind({});
export const Primary: Story<Args> = Template.bind({});
Primary.args = {
label: 'Create new container',
onClick: () => {
alert('Hello AddButton!');
},
};

View File

@ -1,22 +1,18 @@
import { fireEvent, render } from '@testing-library/react';
import { render } from '@/react-tools/test-utils';
import { AddButton, Props } from './AddButton';
import { AddButton } from './AddButton';
function renderDefault({
label = 'default label',
onClick = () => {},
}: Partial<Props> = {}) {
return render(<AddButton label={label} onClick={onClick} />);
}: Partial<{ label: string }> = {}) {
return render(<AddButton to="">{label}</AddButton>);
}
test('should display a AddButton component and allow onClick', async () => {
test('should display a AddButton component', async () => {
const label = 'test label';
const onClick = jest.fn();
const { findByText } = renderDefault({ label, onClick });
const { findByText } = renderDefault({ label });
const buttonLabel = await findByText(label);
expect(buttonLabel).toBeTruthy();
fireEvent.click(buttonLabel);
expect(onClick).toHaveBeenCalled();
});

View File

@ -1,35 +1,38 @@
import clsx from 'clsx';
import { PlusCircle } from 'lucide-react';
import { Plus } from 'lucide-react';
import { ComponentProps, PropsWithChildren } from 'react';
import { Icon } from '@/react/components/Icon';
import { AutomationTestingProps } from '@/types';
import styles from './AddButton.module.css';
import { Link } from '@@/Link';
export interface Props {
className?: string;
label: string;
disabled?: boolean;
onClick: () => void;
}
import { Button } from './Button';
export function AddButton({ label, onClick, className, disabled }: Props) {
export function AddButton({
to = '.new',
params,
children,
color = 'primary',
disabled,
'data-cy': dataCy,
}: PropsWithChildren<
{
to?: string;
params?: object;
color?: ComponentProps<typeof Button>['color'];
disabled?: boolean;
} & AutomationTestingProps
>) {
return (
<button
className={clsx(
className,
'label',
'label-default',
'vertical-center',
'interactive',
'vertical-center',
styles.addButton
)}
type="button"
onClick={onClick}
<Button
as={Link}
props={{ to, params }}
icon={Plus}
className="!m-0"
data-cy={dataCy}
color={color}
disabled={disabled}
>
<Icon icon={PlusCircle} />
{label}
</button>
{children || 'Add'}
</Button>
);
}

View File

@ -0,0 +1,40 @@
import { Trash2 } from 'lucide-react';
import { ComponentProps, PropsWithChildren, ReactNode } from 'react';
import { confirmDelete } from '@@/modals/confirm';
import { Button } from './Button';
export function DeleteButton({
disabled,
confirmMessage,
onConfirmed,
size,
children,
}: PropsWithChildren<{
size?: ComponentProps<typeof Button>['size'];
disabled?: boolean;
confirmMessage: ReactNode;
onConfirmed(): Promise<void> | void;
}>) {
return (
<Button
size={size}
color="dangerlight"
disabled={disabled}
onClick={() => handleClick()}
icon={Trash2}
className="!m-0"
>
{children || 'Remove'}
</Button>
);
async function handleClick() {
if (!(await confirmDelete(confirmMessage))) {
return undefined;
}
return onConfirmed();
}
}

View File

@ -0,0 +1,24 @@
import { useCurrentStateAndParams } from '@uirouter/react';
import { AutomationTestingProps } from '@/types';
import { AddButton } from '@@/buttons';
export function CreateFromManifestButton({
params = {},
'data-cy': dataCy,
}: { params?: object } & AutomationTestingProps) {
const { state } = useCurrentStateAndParams();
return (
<AddButton
to="kubernetes.deploy"
params={{
referrer: state.name,
...params,
}}
data-cy={dataCy}
>
Create from manifest
</AddButton>
);
}