Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions i18n/en-US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,16 @@ be.sort = Sort
be.statusSkill = Status
# Generic success label.
be.success = Success
# aria-label for the task modal close button
be.taskModalV2.close = Close
# Title of the modal for creating an approval task
be.taskModalV2.createApprovalTask = Create Approval Task
# Title of the modal for creating a general task
be.taskModalV2.createGeneralTask = Create General Task
# Title of the modal for editing an existing approval task
be.taskModalV2.editApprovalTask = Modify Approval Task
# Title of the modal for editing an existing general task
be.taskModalV2.editGeneralTask = Modify General Task
# Shown instead of todays date.
be.today = today
# Label for keywords/topics skill section in the preview sidebar
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.bcs-NewTaskModal {
display: flex;
flex-direction: column;
gap: var(--bp-space-040);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as React from 'react';
import { useIntl } from 'react-intl';
import type { MessageDescriptor } from 'react-intl';

import { Modal } from '@box/blueprint-web';

import { TASK_EDIT_MODE_CREATE, TASK_TYPE_APPROVAL, TASK_TYPE_GENERAL } from '../../../../constants';

import type { TaskEditMode, TaskType } from '../../../../common/types/tasks';

import messages from './messages';

import './TaskModalV2.scss';

export type TaskModalV2Props = {
editMode?: TaskEditMode;
isOpen: boolean;
onClose: () => void;
taskType: TaskType;
};

const getTitleMessage = (taskType: TaskType, editMode: TaskEditMode): MessageDescriptor => {
const isCreate = editMode === TASK_EDIT_MODE_CREATE;
if (taskType === TASK_TYPE_GENERAL) {
return isCreate ? messages.createGeneralTaskTitle : messages.editGeneralTaskTitle;
}
return isCreate ? messages.createApprovalTaskTitle : messages.editApprovalTaskTitle;
};

const TaskModalV2 = ({
editMode = TASK_EDIT_MODE_CREATE,
isOpen,
onClose,
taskType = TASK_TYPE_APPROVAL,
}: TaskModalV2Props) => {
const { formatMessage } = useIntl();
const titleMessage = getTitleMessage(taskType, editMode);

const handleOpenChange = (open: boolean) => {
if (!open) {
onClose();
}
};

return (
<Modal open={isOpen} onOpenChange={handleOpenChange}>
<Modal.Content className="bcs-NewTaskModal" data-testid="task-modal-v2" size="medium">
<Modal.Header>{formatMessage(titleMessage)}</Modal.Header>
<Modal.Body>
<div>Form goes here</div>
</Modal.Body>
<Modal.Close aria-label={formatMessage(messages.closeLabel)} />
</Modal.Content>
</Modal>
);
};

export default TaskModalV2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';

import { render, screen, userEvent } from '../../../../../test-utils/testing-library';
import {
TASK_EDIT_MODE_CREATE,
TASK_EDIT_MODE_EDIT,
TASK_TYPE_APPROVAL,
TASK_TYPE_GENERAL,
} from '../../../../../constants';
import TaskModalV2 from '../TaskModalV2';

import type { TaskModalV2Props } from '../TaskModalV2';

describe('elements/content-sidebar/task-modal-v2/TaskModalV2', () => {
const renderModal = (props: Partial<TaskModalV2Props> = {}) =>
render(<TaskModalV2 isOpen onClose={jest.fn()} taskType={TASK_TYPE_APPROVAL} {...props} />);

test('renders nothing when isOpen is false', () => {
renderModal({ isOpen: false });
expect(screen.queryByTestId('task-modal-v2')).not.toBeInTheDocument();
});

test('renders the modal with a placeholder form region when isOpen is true', () => {
renderModal();
expect(screen.getByTestId('task-modal-v2')).toBeVisible();
expect(screen.getByText('Form goes here')).toBeVisible();
});

test.each([
[TASK_TYPE_APPROVAL, TASK_EDIT_MODE_CREATE, 'Create Approval Task'],
[TASK_TYPE_APPROVAL, TASK_EDIT_MODE_EDIT, 'Modify Approval Task'],
[TASK_TYPE_GENERAL, TASK_EDIT_MODE_CREATE, 'Create General Task'],
[TASK_TYPE_GENERAL, TASK_EDIT_MODE_EDIT, 'Modify General Task'],
])('renders the correct title for taskType=%s editMode=%s', (taskType, editMode, expectedTitle) => {
renderModal({ taskType, editMode });
expect(screen.getByRole('heading', { name: expectedTitle })).toBeVisible();
});

test('calls onClose when the close button is clicked', async () => {
const user = userEvent();
const onClose = jest.fn();
renderModal({ onClose });
await user.click(screen.getByRole('button', { name: 'Close' }));
expect(onClose).toHaveBeenCalledTimes(1);
});

test('calls onClose when Escape is pressed', async () => {
const user = userEvent();
const onClose = jest.fn();
renderModal({ onClose });
await user.keyboard('{Escape}');
expect(onClose).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './TaskModalV2';
export type { TaskModalV2Props } from './TaskModalV2';
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineMessages } from 'react-intl';

const messages = defineMessages({
closeLabel: {
id: 'be.taskModalV2.close',
defaultMessage: 'Close',
description: 'aria-label for the task modal close button',
},
createApprovalTaskTitle: {
id: 'be.taskModalV2.createApprovalTask',
defaultMessage: 'Create Approval Task',
description: 'Title of the modal for creating an approval task',
},
createGeneralTaskTitle: {
id: 'be.taskModalV2.createGeneralTask',
defaultMessage: 'Create General Task',
description: 'Title of the modal for creating a general task',
},
editApprovalTaskTitle: {
id: 'be.taskModalV2.editApprovalTask',
defaultMessage: 'Modify Approval Task',
description: 'Title of the modal for editing an existing approval task',
},
editGeneralTaskTitle: {
id: 'be.taskModalV2.editGeneralTask',
defaultMessage: 'Modify General Task',
description: 'Title of the modal for editing an existing general task',
},
});

export default messages;
Loading