Skip to content

Commit eb9f5b8

Browse files
fix(apollo-react): disable task three-dot menu while task is loading [MST-8171]
1 parent ea842ce commit eb9f5b8

11 files changed

Lines changed: 304 additions & 37 deletions

File tree

packages/apollo-react/src/canvas/components/StageNode/AdhocTask.test.tsx

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, screen, waitFor } from '@testing-library/react';
1+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
22
import userEvent from '@testing-library/user-event';
33
import { describe, expect, it, vi } from 'vitest';
44
import type { NodeMenuItem } from '../NodeContextMenu';
@@ -264,4 +264,76 @@ describe('AdhocTaskItem', () => {
264264
});
265265
});
266266
});
267+
268+
describe('Task Loading State', () => {
269+
it('disables menu button when isTaskLoading is true', () => {
270+
const onRemove = vi.fn();
271+
const menuItems = createMenuItems(onRemove);
272+
273+
render(
274+
<AdhocTaskItem
275+
{...defaultProps}
276+
getContextMenuItems={() => menuItems}
277+
isTaskLoading={true}
278+
/>
279+
);
280+
281+
const menuButton = screen.getByTestId('stage-task-menu-adhoc-1');
282+
expect(menuButton).toBeDisabled();
283+
});
284+
285+
it('does not disable menu button when isTaskLoading is false', () => {
286+
const onRemove = vi.fn();
287+
const menuItems = createMenuItems(onRemove);
288+
289+
render(
290+
<AdhocTaskItem
291+
{...defaultProps}
292+
getContextMenuItems={() => menuItems}
293+
isTaskLoading={false}
294+
/>
295+
);
296+
297+
const menuButton = screen.getByTestId('stage-task-menu-adhoc-1');
298+
expect(menuButton).not.toBeDisabled();
299+
});
300+
301+
it('does not open menu when clicking a disabled menu button', () => {
302+
const onRemove = vi.fn();
303+
const menuItems = createMenuItems(onRemove);
304+
305+
render(
306+
<AdhocTaskItem
307+
{...defaultProps}
308+
getContextMenuItems={() => menuItems}
309+
isTaskLoading={true}
310+
/>
311+
);
312+
313+
const menuButton = screen.getByTestId('stage-task-menu-adhoc-1');
314+
expect(menuButton).toBeDisabled();
315+
316+
fireEvent.click(menuButton);
317+
expect(screen.queryByText('Replace task')).not.toBeInTheDocument();
318+
});
319+
320+
it('does not open menu on right-click when isTaskLoading is true', async () => {
321+
const user = userEvent.setup();
322+
const onRemove = vi.fn();
323+
const menuItems = createMenuItems(onRemove);
324+
325+
render(
326+
<AdhocTaskItem
327+
{...defaultProps}
328+
getContextMenuItems={() => menuItems}
329+
isTaskLoading={true}
330+
/>
331+
);
332+
333+
const task = screen.getByTestId('stage-task-adhoc-1');
334+
await user.pointer({ keys: '[MouseRight]', target: task });
335+
336+
expect(screen.queryByText('Replace task')).not.toBeInTheDocument();
337+
});
338+
});
267339
});

packages/apollo-react/src/canvas/components/StageNode/AdhocTask.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface AdhocTaskItemProps {
1212
getContextMenuItems?: () => NodeMenuItem[];
1313
onTaskClick: (e: React.MouseEvent, taskId: string) => void;
1414
onTaskPlay?: (taskId: string) => Promise<void>;
15+
isTaskLoading?: boolean;
1516
}
1617

1718
const AdhocTaskItemComponent = ({
@@ -21,6 +22,7 @@ const AdhocTaskItemComponent = ({
2122
getContextMenuItems,
2223
onTaskClick,
2324
onTaskPlay,
25+
isTaskLoading,
2426
}: AdhocTaskItemProps) => {
2527
const taskRef = useRef<HTMLDivElement>(null);
2628
const menuRef = useRef<TaskMenuHandle>(null);
@@ -43,11 +45,16 @@ const AdhocTaskItemComponent = ({
4345
selected={isSelected}
4446
status={taskExecution?.status}
4547
onClick={handleClick}
46-
{...(getContextMenuItems && { onContextMenu: handleContextMenu })}
48+
{...(getContextMenuItems && !isTaskLoading && { onContextMenu: handleContextMenu })}
4749
>
4850
<TaskContent task={task} taskExecution={taskExecution} onTaskPlay={onTaskPlay} />
4951
{getContextMenuItems && (
50-
<TaskMenu ref={menuRef} taskId={task.id} getContextMenuItems={getContextMenuItems} />
52+
<TaskMenu
53+
ref={menuRef}
54+
taskId={task.id}
55+
getContextMenuItems={getContextMenuItems}
56+
disabled={isTaskLoading}
57+
/>
5158
)}
5259
</StageTask>
5360
);

packages/apollo-react/src/canvas/components/StageNode/DraggableTask.test.tsx

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, screen, waitFor } from '@testing-library/react';
1+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
22
import userEvent from '@testing-library/user-event';
33
import { describe, expect, it, vi } from 'vitest';
44
import type { NodeMenuItem } from '../NodeContextMenu';
@@ -314,6 +314,78 @@ describe('DraggableTask', () => {
314314
});
315315
});
316316

317+
describe('Task Loading State', () => {
318+
it('disables menu button when isTaskLoading is true', () => {
319+
const onRemove = vi.fn();
320+
const menuItems = createMenuItems(onRemove);
321+
322+
render(
323+
<DraggableTask
324+
{...defaultProps}
325+
getContextMenuItems={() => menuItems}
326+
isTaskLoading={true}
327+
/>
328+
);
329+
330+
const menuButton = screen.getByTestId('stage-task-menu-task-1');
331+
expect(menuButton).toBeDisabled();
332+
});
333+
334+
it('does not disable menu button when isTaskLoading is false', () => {
335+
const onRemove = vi.fn();
336+
const menuItems = createMenuItems(onRemove);
337+
338+
render(
339+
<DraggableTask
340+
{...defaultProps}
341+
getContextMenuItems={() => menuItems}
342+
isTaskLoading={false}
343+
/>
344+
);
345+
346+
const menuButton = screen.getByTestId('stage-task-menu-task-1');
347+
expect(menuButton).not.toBeDisabled();
348+
});
349+
350+
it('does not open menu when clicking a disabled menu button', () => {
351+
const onRemove = vi.fn();
352+
const menuItems = createMenuItems(onRemove);
353+
354+
render(
355+
<DraggableTask
356+
{...defaultProps}
357+
getContextMenuItems={() => menuItems}
358+
isTaskLoading={true}
359+
/>
360+
);
361+
362+
const menuButton = screen.getByTestId('stage-task-menu-task-1');
363+
expect(menuButton).toBeDisabled();
364+
365+
fireEvent.click(menuButton);
366+
expect(screen.queryByText('Move Up')).not.toBeInTheDocument();
367+
});
368+
369+
it('does not open menu on right-click when isTaskLoading is true', async () => {
370+
const user = userEvent.setup();
371+
const onRemove = vi.fn();
372+
const menuItems = createMenuItems(onRemove);
373+
374+
render(
375+
<DraggableTask
376+
{...defaultProps}
377+
getContextMenuItems={() => menuItems}
378+
isTaskLoading={true}
379+
/>
380+
);
381+
382+
const task = screen.getByTestId('stage-task-task-1');
383+
await user.pointer({ keys: '[MouseRight]', target: task });
384+
385+
expect(screen.queryByText('Move Up')).not.toBeInTheDocument();
386+
});
387+
});
388+
317389
describe('Task Rendering', () => {
318390
it('renders task label', () => {
319391
render(<DraggableTask {...defaultProps} />);

packages/apollo-react/src/canvas/components/StageNode/DraggableTask.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const DraggableTaskComponent = ({
2626
onTaskClick,
2727
isDragDisabled,
2828
projectedDepth,
29+
isTaskLoading,
2930
}: DraggableTaskProps) => {
3031
const zoom = useStore((s) => s.transform[2]);
3132
const taskRef = useRef<HTMLDivElement>(null);
@@ -94,7 +95,7 @@ const DraggableTaskComponent = ({
9495
isParallel={isParallel}
9596
isDragEnabled={!isDragDisabled}
9697
onClick={handleClick}
97-
{...(getContextMenuItems && { onContextMenu: handleContextMenu })}
98+
{...(getContextMenuItems && !isTaskLoading && { onContextMenu: handleContextMenu })}
9899
>
99100
<TaskContent task={task} taskExecution={taskExecution} />
100101

@@ -113,7 +114,12 @@ const DraggableTaskComponent = ({
113114
</CanvasTooltip>
114115
)}
115116
{getContextMenuItems && (
116-
<TaskMenu ref={menuRef} taskId={task.id} getContextMenuItems={handleGetContextMenuItems} />
117+
<TaskMenu
118+
ref={menuRef}
119+
taskId={task.id}
120+
getContextMenuItems={handleGetContextMenuItems}
121+
disabled={isTaskLoading}
122+
/>
117123
)}
118124
</StageTask>
119125
);

packages/apollo-react/src/canvas/components/StageNode/DraggableTask.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export interface DraggableTaskProps {
1313
onTaskPlay?: (taskId: string) => Promise<void>;
1414
isDragDisabled?: boolean;
1515
projectedDepth?: number;
16+
isTaskLoading?: boolean;
1617
}

0 commit comments

Comments
 (0)