Skip to content

Commit

Permalink
Web: fix back button for guided bot flows to return to previous locat…
Browse files Browse the repository at this point in the history
…ion (#42340) (#42396)

* "Bot guided flow back button for first step correctly routes to previous loc"

* Remove pointer events for existing or disabled integration tiles
  • Loading branch information
kimlisa authored Jun 4, 2024
1 parent 6661de9 commit 706516d
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 19 deletions.
5 changes: 4 additions & 1 deletion web/packages/teleport/src/Bots/Add/AddBotsPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ function GuidedTile({ integration }: { integration: BotIntegration }) {
return (
<IntegrationTile
as={Link}
to={integration.link}
to={{
pathname: integration.link,
state: { previousPathname: location.pathname },
}}
onClick={() => {
userEventService.captureIntegrationEnrollEvent({
event: IntegrationEnrollEvent.Started,
Expand Down
64 changes: 53 additions & 11 deletions web/packages/teleport/src/Bots/Add/Shared/FlowButtons.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
*/

import { render, screen, userEvent } from 'design/utils/testing';
import { createMemoryHistory } from 'history';
import { Router, MemoryRouter } from 'react-router';
import React from 'react';

import cfg from 'teleport/config';

import { FlowButtons, FlowButtonsProps } from './FlowButtons';

describe('flowButtons component', () => {
Expand All @@ -42,11 +46,13 @@ describe('flowButtons component', () => {

it('disables the buttons according to the props', () => {
render(
<FlowButtons
{...props}
backButton={{ disabled: true }}
nextButton={{ disabled: true }}
/>
<MemoryRouter>
<FlowButtons
{...props}
backButton={{ disabled: true }}
nextButton={{ disabled: true }}
/>
</MemoryRouter>
);

expect(screen.getByTestId('button-back')).toBeDisabled();
Expand All @@ -55,11 +61,13 @@ describe('flowButtons component', () => {

it('hides the buttons according to the props', () => {
render(
<FlowButtons
{...props}
backButton={{ hidden: true }}
nextButton={{ hidden: true }}
/>
<MemoryRouter>
<FlowButtons
{...props}
backButton={{ hidden: true }}
nextButton={{ hidden: true }}
/>
</MemoryRouter>
);

expect(screen.queryByTestId('button-back')).not.toBeInTheDocument();
Expand All @@ -69,12 +77,46 @@ describe('flowButtons component', () => {
it('triggers the correct click handler', async () => {
const prevMock = jest.fn();
const nextMock = jest.fn();
render(<FlowButtons {...props} prevStep={prevMock} nextStep={nextMock} />);
render(
<MemoryRouter>
<FlowButtons {...props} prevStep={prevMock} nextStep={nextMock} />
</MemoryRouter>
);

await userEvent.click(screen.getByTestId('button-back'));
expect(prevMock).toHaveBeenCalledTimes(1);

await userEvent.click(screen.getByTestId('button-next'));
expect(nextMock).toHaveBeenCalledTimes(1);
});

test('when useLocation.state is defined, the first step back button uses this state as pathname', async () => {
const history = createMemoryHistory({
initialEntries: [{ state: { previousPathname: 'web/random/route' } }],
});
history.push = jest.fn();

render(
<Router history={history}>
<FlowButtons {...props} isFirstStep={true} />
</Router>
);

await userEvent.click(screen.getByTestId('button-back-first-step'));
expect(history.push).toHaveBeenCalledWith('web/random/route');
});

test('when useLocation.state is NOT defined, the first step back button defaults to bots pathname', async () => {
const history = createMemoryHistory();
history.push = jest.fn();

render(
<Router history={history}>
<FlowButtons {...props} isFirstStep={true} />
</Router>
);

await userEvent.click(screen.getByTestId('button-back-first-step'));
expect(history.push).toHaveBeenCalledWith(cfg.getBotsNewRoute());
});
});
6 changes: 4 additions & 2 deletions web/packages/teleport/src/Bots/Add/Shared/FlowButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import React from 'react';
import { Link } from 'react-router-dom';
import { Link, useLocation } from 'react-router-dom';

import { ButtonPrimary, ButtonSecondary } from 'design/Button';

Expand Down Expand Up @@ -77,12 +77,14 @@ function BackButton({
disabled: boolean;
prevStep: () => void;
}) {
const location = useLocation<{ previousPathname: string }>();

if (isFirstStep) {
return (
<ButtonSecondary
disabled={disabled}
as={Link}
to={cfg.getBotsNewRoute()}
to={location.state?.previousPathname || cfg.getBotsNewRoute()}
data-testid="button-back-first-step"
>
Back
Expand Down
8 changes: 4 additions & 4 deletions web/packages/teleport/src/Bots/Add/Shared/GuidedFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ export type FlowProps = {
};

export function GuidedFlow({ name, title, views, icon }: FlowProps) {
if (views.length < 1) {
return null;
}

const steps = views.length;
let [currentStep, setCurrentStep] = useState(0);

if (steps < 1) {
return null;
}

function handleNextStep() {
if (currentStep < steps - 1) {
setCurrentStep(currentStep + 1);
Expand Down
3 changes: 2 additions & 1 deletion web/packages/teleport/src/Integrations/Enroll/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const IntegrationTile = styled(Flex)`
cursor: pointer;
${props => {
const pointerEvents = props.disabled ? 'none' : null;
const pointerEvents = props.disabled || props.$exists ? 'none' : null;
if (props.$exists) {
return { pointerEvents };
}
Expand All @@ -44,6 +44,7 @@ export const IntegrationTile = styled(Flex)`
&:hover {
background-color: ${props.theme.colors.buttons.secondary.hover};
}
pointer-events: ${pointerEvents};
`;
}}
`;
Expand Down

0 comments on commit 706516d

Please sign in to comment.