-
Notifications
You must be signed in to change notification settings - Fork 340
feat(ui-uplift): BP AddTaskButtonV2 #4366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(ui-uplift): BP AddTaskButtonV2 #4366
Conversation
|
|
WalkthroughAdds AddTaskButtonV2 and AddTaskMenuV2 React components with SCSS styling and tests. The button component manages task-type selection, modal open/close, submission error state, and supports router-based or internal sidebar navigation. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Menu as AddTaskMenuV2
participant Button as AddTaskButtonV2
participant Nav as Navigation
participant Modal as TaskModal
User->>Menu: Click trigger
Menu->>Menu: Open menu
User->>Menu: Select task item (General/Approval)
Menu->>Button: onMenuItemClick(taskType)
Button->>Button: set taskType, isTaskFormOpen = true
alt Router enabled
Button->>Nav: history.replace({ open: true })
else Router disabled
Button->>Nav: internalSidebarNavigationHandler({ open: true, ...state })
end
Button->>Modal: Render TaskModal with taskFormProps
User->>Modal: Submit or Close
alt Submit error
Modal->>Button: handleSubmitError(error)
else Close/Success
Modal->>Button: handleModalClose()
Button->>Button: clear error, refocus trigger
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/elements/content-sidebar/__tests__/AddTaskMenuV2.test.tsx (1)
82-88: Consider verifying the ref argument type.The test confirms the callback is invoked but doesn't verify it receives an HTMLButtonElement. For more robust coverage, consider asserting the argument type.
test('should call setAddTaskButtonRef with button element', () => { const setAddTaskButtonRef = jest.fn(); renderComponent({ setAddTaskButtonRef }); expect(setAddTaskButtonRef).toHaveBeenCalled(); + expect(setAddTaskButtonRef).toHaveBeenCalledWith(expect.any(HTMLButtonElement)); });src/elements/content-sidebar/AddTaskMenuV2.scss (1)
28-36: Consider using design tokens for typography.If the project has design tokens for font-weight, font-size, and line-height values, consider using them for consistency across the codebase.
src/elements/content-sidebar/AddTaskMenuV2.tsx (1)
80-80: Prefer useIntl hook over injectIntl HOC in TypeScript files.Based on the codebase pattern, TypeScript files should use the modern useIntl hook instead of the injectIntl HOC for consistency with other new TypeScript components.
Based on learnings
Apply this refactor:
-import { injectIntl, IntlShape } from 'react-intl'; +import { useIntl } from 'react-intl'; import { DropdownMenu, TriggerButton } from '@box/blueprint-web'; import ApprovalTask from '@box/blueprint-web-assets/icons/Fill/ApprovalTask'; import Tasks from '@box/blueprint-web-assets/icons/MediumFilled/Tasks'; import messages from './messages'; import { TASK_TYPE_APPROVAL, TASK_TYPE_GENERAL } from '../../constants'; import type { TaskType } from '../../common/types/tasks'; import './AddTaskMenuV2.scss'; type Props = { isDisabled: boolean; onMenuItemClick: (taskType: TaskType) => void; setAddTaskButtonRef?: (element: HTMLButtonElement | null) => void; - intl: IntlShape; }; -const AddTaskMenuV2: React.FC<Props> = ({ isDisabled, onMenuItemClick, setAddTaskButtonRef, intl }) => { +const AddTaskMenuV2: React.FC<Props> = ({ isDisabled, onMenuItemClick, setAddTaskButtonRef }) => { + const intl = useIntl(); const [isOpen, setIsOpen] = React.useState(false); // ... rest of component -export default injectIntl(AddTaskMenuV2); +export default AddTaskMenuV2;src/elements/content-sidebar/AddTaskButtonV2.tsx (1)
107-108: Prefer useIntl hook over injectIntl HOC in TypeScript files.Based on the codebase pattern, TypeScript files should use the modern useIntl hook instead of the injectIntl HOC for consistency with other new TypeScript components.
Based on learnings
Apply this refactor:
-import { injectIntl, IntlShape } from 'react-intl'; +import { useIntl } from 'react-intl'; import { withRouterIfEnabled } from '../common/routing'; import AddTaskMenuV2 from './AddTaskMenuV2'; import TaskModal from './TaskModal'; import { TASK_TYPE_APPROVAL } from '../../constants'; import type { TaskFormProps } from './activity-feed/task-form/TaskForm'; import type { TaskType } from '../../common/types/tasks'; import type { ElementsXhrError } from '../../common/types/api'; import type { InternalSidebarNavigation, InternalSidebarNavigationHandler } from '../common/types/SidebarNavigation'; export type AddTaskButtonV2Props = { history?: History; internalSidebarNavigation?: InternalSidebarNavigation; internalSidebarNavigationHandler?: InternalSidebarNavigationHandler; isDisabled?: boolean; onTaskModalClose: () => void; routerDisabled?: boolean; taskFormProps: TaskFormProps; - intl: IntlShape; }; const AddTaskButtonV2: React.FC<AddTaskButtonV2Props> = ({ history, internalSidebarNavigation, internalSidebarNavigationHandler, isDisabled = false, onTaskModalClose, routerDisabled, taskFormProps, }) => { + const intl = useIntl(); const buttonRef = React.useRef<HTMLButtonElement>(null); // ... rest of component export { AddTaskButtonV2 as AddTaskButtonV2Component }; -export default withRouterIfEnabled(injectIntl(AddTaskButtonV2)); +export default withRouterIfEnabled(AddTaskButtonV2);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/elements/content-sidebar/AddTaskButtonV2.tsx(1 hunks)src/elements/content-sidebar/AddTaskMenuV2.scss(1 hunks)src/elements/content-sidebar/AddTaskMenuV2.tsx(1 hunks)src/elements/content-sidebar/__tests__/AddTaskButtonV2.test.tsx(1 hunks)src/elements/content-sidebar/__tests__/AddTaskMenuV2.test.tsx(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-11T14:43:02.677Z
Learnt from: jpan-box
Repo: box/box-ui-elements PR: 4166
File: src/elements/content-sidebar/SidebarNav.js:126-126
Timestamp: 2025-07-11T14:43:02.677Z
Learning: In the box-ui-elements repository, there's a file-type-based pattern for internationalization: TypeScript files (.tsx) predominantly use the modern useIntl hook (41 vs 15 files), while JavaScript files (.js) predominantly use the legacy injectIntl HOC (64 vs 5 files). New TypeScript components should use useIntl, while existing JavaScript components typically continue using injectIntl for consistency.
Applied to files:
src/elements/content-sidebar/AddTaskMenuV2.tsxsrc/elements/content-sidebar/AddTaskButtonV2.tsx
📚 Learning: 2025-08-15T14:42:01.840Z
Learnt from: jpan-box
Repo: box/box-ui-elements PR: 4227
File: src/elements/common/sub-header/SubHeader.tsx:19-19
Timestamp: 2025-08-15T14:42:01.840Z
Learning: In SubHeader.tsx, the bulkItemActionMenuProps prop is intentionally required (not optional) because there will always be a default "Download" action available, ensuring the prop is never undefined in actual usage.
Applied to files:
src/elements/content-sidebar/AddTaskMenuV2.tsxsrc/elements/content-sidebar/AddTaskButtonV2.tsx
🧬 Code graph analysis (2)
src/elements/content-sidebar/__tests__/AddTaskButtonV2.test.tsx (1)
src/elements/content-sidebar/AddTaskButtonV2.tsx (1)
AddTaskButtonV2(107-107)
src/elements/content-sidebar/AddTaskButtonV2.tsx (2)
src/elements/common/types/SidebarNavigation.ts (2)
InternalSidebarNavigation(49-51)InternalSidebarNavigationHandler(55-55)src/elements/common/routing/withRouterIfEnabled.js (1)
withRouterIfEnabled(6-23)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: lint_test_build
- GitHub Check: Summary
🔇 Additional comments (13)
src/elements/content-sidebar/__tests__/AddTaskMenuV2.test.tsx (3)
1-30: LGTM! Clean test setup.The test infrastructure is well-organized with appropriate mocking and test utilities. The TooltipProvider wrapper correctly accommodates Blueprint Web component requirements.
31-44: LGTM! Good accessibility test coverage.These tests properly verify the component's basic rendering and disabled state using accessible role queries.
46-80: LGTM! Comprehensive interaction tests.Both menu item click tests properly validate the user interaction flow and verify that the correct task type is passed to the callback.
src/elements/content-sidebar/AddTaskMenuV2.scss (2)
1-8: LGTM! Clean SCSS structure.The imports and container styling follow proper patterns with appropriate use of constants and design tokens.
10-26: LGTM! Proper layout implementation.The flexbox layout with gap and the icon styling with fixed dimensions ensure consistent presentation.
src/elements/content-sidebar/__tests__/AddTaskButtonV2.test.tsx (2)
1-104: LGTM! Comprehensive test coverage.The test suite thoroughly validates:
- History state management for keeping sidebar open
- Modal open/close lifecycle
- Callback invocations
- State transitions
The inline comments at lines 32-35 helpfully document the design rationale for the history state management.
106-152: LGTM! Router-disabled scenario coverage.These tests properly validate the alternative navigation path when routing is disabled, including state preservation.
src/elements/content-sidebar/AddTaskMenuV2.tsx (2)
1-19: LGTM! Clean imports and type definitions.The props interface is well-defined with appropriate required and optional fields.
20-41: LGTM! Proper state and callback management.The component correctly manages dropdown state and memoizes the menu item click handler with appropriate dependencies.
src/elements/content-sidebar/AddTaskButtonV2.tsx (4)
1-24: LGTM! Well-structured imports and type definitions.The component props are comprehensively typed with appropriate optional fields for flexible integration.
25-62: LGTM! Proper state management and router handling.The component correctly handles both router-enabled and router-disabled navigation scenarios. The inline comments at lines 39-42 helpfully document the design rationale for the history state management.
63-86: LGTM! Proper cleanup and focus management.The modal close handler appropriately cleans up state and restores focus to the trigger button. The setTimeout pattern ensures focus occurs after React's state updates complete.
87-105: LGTM! Clean component composition.The component properly renders the menu and modal with appropriate props, maintaining clear separation of concerns.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary
Implements new Blueprint-based versions of AddTaskButton and AddTaskMenu components with corresponding test coverage.
Changes
Key Improvements
Screenshots
Summary by CodeRabbit
New Features
Style
Tests