Skip to content

Commit

Permalink
change: [M3-7813] - Allow the disabling of the TypeToConfirm input (#…
Browse files Browse the repository at this point in the history
…10251)

* Allow disabling type to confirm input

* PlacementGroupDelete update

* Improve coverage

* feedback and update interface

* Improve coverage
  • Loading branch information
abailly-akamai authored Mar 6, 2024
1 parent f8ce5e6 commit d4bb18e
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fireEvent } from '@testing-library/react';
import * as React from 'react';

import { Typography } from 'src/components/Typography';
Expand Down Expand Up @@ -33,4 +34,91 @@ describe('TypeToConfirmDialog Component', () => {
);
getByText(warningText);
});

it('should have its button disabled by default', () => {
const { getByTestId } = renderWithTheme(
<TypeToConfirmDialog
entity={{
action: 'deletion',
name: 'test',
primaryBtnText: 'Delete',
type: 'Linode',
}}
label={'Linode Label'}
loading={false}
open={true}
title="Delete Linode test?"
{...props}
>
<Typography style={{ fontSize: '0.875rem' }}>
<strong>Warning:</strong> {warningText}
</Typography>
</TypeToConfirmDialog>
);

const submitButton = getByTestId('confirm');
expect(submitButton).toBeDisabled();

const input = getByTestId('textfield-input');
fireEvent.change(input, { target: { value: 'test' } });

expect(submitButton).toBeEnabled();
});

it('should disabled the Type To Confirm input field given the `disableTypeToConfirmInput` prop', () => {
const { getByTestId } = renderWithTheme(
<TypeToConfirmDialog
entity={{
action: 'deletion',
name: 'test',
primaryBtnText: 'Delete',
type: 'Linode',
}}
disableTypeToConfirmInput
label={'Linode Label'}
loading={false}
open={true}
title="Delete Linode test?"
{...props}
>
<Typography style={{ fontSize: '0.875rem' }}>
<strong>Warning:</strong> {warningText}
</Typography>
</TypeToConfirmDialog>
);

const input = getByTestId('textfield-input');
expect(input).toBeDisabled();
});

it('should disabled the Type To Confirm input field given the prop', () => {
const { getByTestId } = renderWithTheme(
<TypeToConfirmDialog
entity={{
action: 'deletion',
name: 'test',
primaryBtnText: 'Delete',
type: 'Linode',
}}
disableTypeToConfirmSubmit
label={'Linode Label'}
loading={false}
open={true}
title="Delete Linode test?"
{...props}
>
<Typography style={{ fontSize: '0.875rem' }}>
<strong>Warning:</strong> {warningText}
</Typography>
</TypeToConfirmDialog>
);

const input = getByTestId('textfield-input');
fireEvent.change(input, { target: { value: 'test' } });

const submitButton = getByTestId('confirm');
// Should still be disabled cause we overrode the disabled state with the prop

expect(submitButton).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,53 @@ interface EntityInfo {
}

interface TypeToConfirmDialogProps {
/**
* Chidlren are rendered above the TypeToConfirm input
*/
children?: React.ReactNode;
/**
* Props to be allow disabling the input
*/
disableTypeToConfirmInput?: boolean;
/**
* Props to be allow disabling the submit button
*/
disableTypeToConfirmSubmit?: boolean;
/**
* The entity being confirmed
*/
entity: EntityInfo;
/**
* Error to be displayed in the dialog
*/
errors?: APIError[] | null | undefined;
/*
* The label for the dialog
*/
label: string;
/**
* The loading state of dialog
*/
loading: boolean;
/**
* The click handler for the primary button
*/
onClick: () => void;
/**
* The open/closed state of the dialog
*/
open: boolean;
}

type CombinedProps = TypeToConfirmDialogProps &
ConfirmationDialogProps &
Partial<TypeToConfirmProps>;
Partial<Omit<TypeToConfirmProps, 'disabled'>>;

export const TypeToConfirmDialog = (props: CombinedProps) => {
const {
children,
disableTypeToConfirmInput,
disableTypeToConfirmSubmit,
entity,
errors,
inputProps,
Expand All @@ -64,8 +95,10 @@ export const TypeToConfirmDialog = (props: CombinedProps) => {
const [confirmText, setConfirmText] = React.useState('');

const { data: preferences } = usePreferences();
const disabled =
preferences?.type_to_confirm !== false && confirmText !== entity.name;
const isPrimaryButtonDisabled =
(preferences?.type_to_confirm !== false && confirmText !== entity.name) ||
disableTypeToConfirmSubmit;
const isTypeToConfirmInputDisabled = disableTypeToConfirmInput;

React.useEffect(() => {
if (open) {
Expand All @@ -82,7 +115,7 @@ export const TypeToConfirmDialog = (props: CombinedProps) => {
<ActionsPanel
primaryButtonProps={{
'data-testid': 'confirm',
disabled,
disabled: isPrimaryButtonDisabled,
label: entity.primaryBtnText,
loading,
onClick,
Expand Down Expand Up @@ -120,6 +153,7 @@ export const TypeToConfirmDialog = (props: CombinedProps) => {
setConfirmText(input);
}}
data-testid={'dialog-confirm-text-input'}
disabled={isTypeToConfirmInputDisabled}
expand
hideInstructions={entity.subType === 'CloseAccount'}
inputProps={inputProps}
Expand Down
17 changes: 0 additions & 17 deletions packages/manager/src/features/Account/CloseAccountDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const CloseAccountDialog = ({ closeDialog, open }: Props) => {
);
const [errors, setErrors] = React.useState<APIError[] | undefined>(undefined);
const [comments, setComments] = React.useState<string>('');
const [inputtedUsername, setUsername] = React.useState<string>('');
const [canSubmit, setCanSubmit] = React.useState<boolean>(false);
const { classes } = useStyles();
const history = useHistory();
const { data: profile } = useProfile();
Expand All @@ -42,23 +40,9 @@ const CloseAccountDialog = ({ closeDialog, open }: Props) => {
* intentionally not resetting comments
*/
setErrors(undefined);
setUsername('');
setCanSubmit(false);
}
}, [open]);

/**
* enable the submit button if the user entered their
* username correctly
*/
React.useEffect(() => {
if (inputtedUsername === profile?.username) {
setCanSubmit(true);
} else {
setCanSubmit(false);
}
}, [inputtedUsername, profile]);

const inputRef = React.useCallback(
(node: any) => {
/**
Expand Down Expand Up @@ -103,7 +87,6 @@ const CloseAccountDialog = ({ closeDialog, open }: Props) => {
subType: 'CloseAccount',
type: 'AccountSetting',
}}
disabled={!canSubmit}
inputRef={inputRef}
label={`Please enter your Username (${profile.username}) to confirm.`}
loading={isClosingAccount}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ describe('Kubernetes deletion dialog', () => {
);
const button = getByTestId('confirm');

expect(button).toHaveAttribute('aria-disabled', 'true');
expect(button).toBeDisabled;

await findByTestId('textfield-input');

const input = getByTestId('textfield-input');
fireEvent.change(input, { target: { value: 'this-cluster' } });

expect(button).toHaveAttribute('aria-disabled', 'false');
expect(button).toBeEnabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,8 @@ export const PlacementGroupsDeleteModal = (props: Props) => {
? [{ reason: 'Placement Group not found.' }]
: undefined
}
inputProps={{
disabled: isDisabled,
}}
disabled={isDisabled}
disableTypeToConfirmInput={isDisabled}
disableTypeToConfirmSubmit={isDisabled}
label="Placement Group"
loading={placementGroupDataLoading || deletePlacementLoading}
onClick={onDelete}
Expand Down

0 comments on commit d4bb18e

Please sign in to comment.