[WEB-3759] chore: header revamp for cycles, modules, pages and views#6875
[WEB-3759] chore: header revamp for cycles, modules, pages and views#6875sriramveeraghanta merged 4 commits intopreviewfrom
Conversation
WalkthroughThis pull request introduces a range of updates across components and stores. A new type definition, Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant CSS as CustomSearchSelect
participant HC as Header Component
participant L as Link Component
U->>CSS: Clicks to open options
CSS->>HC: Requests switcherOptions
HC-->>CSS: Provides options (value, query, content)
U->>CSS: Selects an option
CSS->>L: Renders link with selected option
L-->>U: Navigates to target page
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/types/src/common.d.ts (1)
30-36: Consider using generics for type safety in the newICustomSearchSelectOptiontype.The introduction of
ICustomSearchSelectOptionis a good approach to standardize dropdown selections across components. However, usinganyfor thevalueproperty reduces type safety.Consider making the type more type-safe by using a generic parameter:
-export type ICustomSearchSelectOption = { +export type ICustomSearchSelectOption<T = any> = { - value: any; + value: T; query: string; content: React.ReactNode; disabled?: boolean; tooltip?: string | React.ReactNode; };This would allow components to specify the exact type for their values while maintaining backward compatibility with existing code.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx (1)
221-243: Replaced Custom Menu with SearchSelect for improved module selection.Upgraded the module selection UI from a basic menu to a more interactive search select component, allowing users to more easily find and switch between modules. This implements the "switcher for detail pages" objective mentioned in the PR.
One minor issue: The
onChangehandler is currently a no-op function() => {}. Consider implementing proper navigation logic here instead of relying solely on the Link component within each option.- onChange={() => {}} + onChange={(value) => { + if (value && value !== moduleId) { + router.push(`/${workspaceSlug}/projects/${projectId}/modules/${value}`); + } + }}web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx (1)
272-280: ViewQuickActions integration needs accessibility consideration.While the ViewQuickActions component has been properly integrated with custom styling, consider adding an aria-label to improve accessibility for the quick actions button.
<ViewQuickActions parentRef={parentRef} customClassName="flex-shrink-0 flex items-center justify-center size-6 bg-custom-background-80/70 rounded" + aria-label="View quick actions" projectId={projectId.toString()} view={viewDetails} workspaceSlug={workspaceSlug.toString()} />web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx (1)
333-339: Added CycleQuickActions with consistent styling.The CycleQuickActions component is properly integrated with custom styling that matches the design pattern used in other headers. Consider adding an aria-label for better accessibility.
<CycleQuickActions parentRef={parentRef} cycleId={cycleId} projectId={projectId} workspaceSlug={workspaceSlug} customClassName="flex-shrink-0 flex items-center justify-center size-6 bg-custom-background-80/70 rounded" + aria-label="Cycle quick actions" />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
packages/types/src/common.d.ts(1 hunks)packages/ui/src/dropdowns/helper.tsx(2 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx(6 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx(3 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx(2 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx(5 hunks)web/core/components/common/index.ts(1 hunks)web/core/components/common/switcher-label.tsx(1 hunks)web/core/components/cycles/analytics-sidebar/sidebar-header.tsx(0 hunks)web/core/components/cycles/quick-actions.tsx(2 hunks)web/core/components/modules/analytics-sidebar/root.tsx(3 hunks)web/core/components/modules/quick-actions.tsx(2 hunks)web/core/components/pages/list/root.tsx(1 hunks)web/core/components/pages/pages-list-main-content.tsx(1 hunks)web/core/components/views/quick-actions.tsx(2 hunks)web/core/store/pages/project-page.store.ts(4 hunks)
💤 Files with no reviewable changes (1)
- web/core/components/cycles/analytics-sidebar/sidebar-header.tsx
🧰 Additional context used
🧬 Code Definitions (6)
web/core/components/pages/list/root.tsx (1)
web/ce/hooks/store/use-page-store.ts (1)
usePageStore(15-24)
web/core/components/cycles/quick-actions.tsx (1)
packages/ui/src/dropdowns/custom-menu.tsx (1)
CustomMenu(232-232)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (6)
web/ce/hooks/store/use-page.ts (1)
usePage(12-23)web/ce/hooks/store/use-page-store.ts (1)
usePageStore(15-24)web/core/store/router.store.ts (2)
projectId(85-87)workspaceSlug(69-71)web/core/components/common/switcher-label.tsx (1)
SwitcherLabel(13-27)packages/types/src/common.d.ts (1)
ICustomSearchSelectOption(30-36)packages/ui/src/dropdowns/custom-search-select.tsx (1)
CustomSearchSelect(14-218)
packages/ui/src/dropdowns/helper.tsx (1)
packages/types/src/common.d.ts (1)
ICustomSearchSelectOption(30-36)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx (3)
web/core/components/common/switcher-label.tsx (1)
SwitcherLabel(13-27)packages/types/src/common.d.ts (1)
ICustomSearchSelectOption(30-36)packages/ui/src/dropdowns/custom-search-select.tsx (1)
CustomSearchSelect(14-218)
web/core/store/pages/project-page.store.ts (3)
packages/types/src/pages.d.ts (2)
TPageNavigationTabs(27-27)TPageFilters(40-45)web/core/store/router.store.ts (2)
projectId(85-87)workspaceSlug(69-71)web/core/store/pages/project-page.ts (1)
TProjectPage(14-14)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Analyze (javascript)
- GitHub Check: Analyze (python)
🔇 Additional comments (53)
web/core/components/pages/list/root.tsx (1)
20-22: Method name updated to reflect tab-based filtering.The method name change from
getCurrentProjectFilteredPageIdstogetCurrentProjectFilteredPageIdsByTabaccurately reflects that the filtering is based on tabs, making the code more descriptive.web/core/components/modules/quick-actions.tsx (3)
27-27: Good addition of customization option.Adding the
customClassNameproperty enhances the component's flexibility by allowing custom styling.
31-31: Property correctly destructured from props.The
customClassNameproperty is properly destructured from the props.
171-171: Properly implemented custom styling for dropdown.The
customClassNameis correctly passed to theCustomMenucomponent asbuttonClassName, allowing for customized appearance of the menu button.web/core/components/pages/pages-list-main-content.tsx (2)
29-30: Updated method names for tab-based filtering.The destructuring now uses the updated method names
getCurrentProjectFilteredPageIdsByTabandgetCurrentProjectPageIdsByTab, which better describe their functionality.
34-35: Consistently using the updated method names.Both
pageIdsandfilteredPageIdsnow use the new method names, maintaining consistency with the store refactoring.web/core/components/modules/analytics-sidebar/root.tsx (3)
7-7: Cleaned up imports by removing unused icons.The import list has been simplified by removing unnecessary icons like ArchiveRestoreIcon, LinkIcon, Trash2, and ArchiveIcon that were likely used in now-removed functionality.
22-22: Streamlined UI imports, removing unused components.The imports from @plane/ui have been updated to remove unused components that were related to functionality that has been removed.
69-70: Simplified hook usage by removing unused methods.The destructuring of methods from useModule and useEventTracker has been updated to include only the methods that are actually used in the component, removing references to methods associated with the removed functionality.
web/core/store/pages/project-page.store.ts (7)
40-42: Renamed and added methods for better API clarity.The interface has been improved by:
- Renaming
getCurrentProjectPageIdstogetCurrentProjectPageIdsByTabto clearly indicate it filters by tab type- Adding a new
getCurrentProjectPageIdsmethod that takes a projectId parameter to get all pages for a project- Renaming
getCurrentProjectFilteredPageIdstogetCurrentProjectFilteredPageIdsByTabfor consistencyThese changes make the API more intuitive and consistent.
50-50: Made pageType parameter optional for more flexibility.Making the pageType parameter optional in fetchPagesList allows for more flexible usage of the method, particularly when fetching all pages without filtering by type.
129-139: Renamed method with clear "ByTab" indicator.The implementation of the renamed
getCurrentProjectPageIdsByTabmethod maintains the same functionality but with a clearer name that indicates it filters pages based on the tab type.
141-149: Added new method to get all pages for a project.This new implementation of
getCurrentProjectPageIdsfetches all pages associated with a project ID without filtering by tab type, providing a useful utility for components that need all pages.
155-172: Renamed filtered method for consistency.The implementation of
getCurrentProjectFilteredPageIdsByTabmaintains the same functionality but with a renamed method that matches the pattern of other methods and clearly indicates filtering by tab.
197-197: Updated method signature with optional parameter.The signature of
fetchPagesListhas been updated to make the pageType parameter optional, allowing for more flexible method calls.
201-201: Updated method call to use renamed method.The implementation now correctly uses the renamed
getCurrentProjectPageIdsByTabmethod, maintaining consistency with the interface changes.web/core/components/common/index.ts (1)
9-9: Added export for new SwitcherLabel component.Added a new export for the SwitcherLabel component, which is likely part of the header revamp mentioned in the PR objectives for cycles, modules, pages, and views.
web/core/components/cycles/quick-actions.tsx (3)
27-27: Added customClassName property for enhanced flexibility.Added a new optional
customClassNameproperty to the Props interface, which allows parent components to customize the appearance of the quick actions menu button.
31-31: Updated destructuring to include new customClassName property.The component now properly extracts the customClassName from props, making it available for use.
192-192: Applied customClassName to CustomMenu component.The customClassName is now passed to the CustomMenu component as buttonClassName, allowing for custom styling of the menu button from parent components.
web/core/components/views/quick-actions.tsx (3)
25-25: Added new customClassName property for enhanced styling control.The addition of this optional string property allows customization of the menu button styles, aligning with the PR's objective of header revamp.
29-29: Properly destructured the new customClassName prop.The destructuring has been updated to include the new
customClassNameparameter, ensuring it's available for use within the component.
99-99: Successfully implemented custom styling for the menu button.The
customClassNameprop is now properly passed to theCustomMenucomponent throughbuttonClassName, enabling flexible styling of the button element.packages/ui/src/dropdowns/helper.tsx (2)
3-3: Imported standardized option type for dropdown components.The import of
ICustomSearchSelectOptionfrom@plane/typesaligns with the effort to standardize dropdown selection mechanisms across the application.
48-48: Simplified type definition using centralized type.Replacing the inline type definition with the imported
ICustomSearchSelectOptiontype improves code maintainability and ensures consistency across the application. This change is part of the broader standardization of selection components.web/core/components/common/switcher-label.tsx (2)
1-11: Well-structured prop type definition for the new SwitcherLabel component.The
TSwitcherLabelPropstype properly defines the component's interface with optional logo properties and a required icon component, providing flexibility for different use cases.
13-27: Created reusable label component for switcher implementations.The
SwitcherLabelcomponent intelligently handles different logo scenarios and provides text truncation, which is essential for consistent header presentation across cycles, modules, pages, and views as mentioned in the PR objectives.The component follows a clear hierarchy for rendering:
- Logo component (if logo_props.in_use is true)
- Image (if logo_url is provided)
- Default icon (always as fallback)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx (5)
19-24: Updated imports to include necessary type for switcher options.Added
ICustomSearchSelectOptionto the imports, enabling proper typing for the new dropdown selection mechanism.
26-26: Added CustomSearchSelect component import.Imported
CustomSearchSelectfrom "@plane/ui" to replace the previous menu implementation, enhancing the header with the new switcher functionality.
29-29: Added SwitcherLabel component to imports.Imported the newly created
SwitcherLabelcomponent to provide consistent label presentation in the module switcher.
163-164: Renamed variable to reflect updated terminology.Changed
issuesCounttoworkItemsCount, reflecting the application's shift in terminology from "issues" to "work items".
165-180: Created structured options for the module switcher.Well-implemented array of options for the module selector dropdown, with each option containing:
- value: module ID
- query: module name for searchability
- content: React component with properly styled label
This implementation provides a consistent user experience for module selection.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (6)
3-10: The import modifications align with new header functionality.The changes correctly add the necessary imports for the new header switcher functionality, including Link from next/link and the ICustomSearchSelectOption type.
21-21: Updated store imports support the new page switching mechanism.The updated import correctly brings in the necessary hooks and types from the store.
29-29: Added projectId parameter extraction.Good addition of projectId to the useParams hook to support the new project-specific page filtering functionality.
36-45: Enhanced store usage with SWR for efficient data fetching.The implementation correctly uses SWR to fetch the pages list for the current project and keeps it updated. This is a good pattern for data fetching that ensures the component has the latest data.
47-62: Well-structured switcher options implementation.The switcherOptions mapping creates a clean data structure for the dropdown selection, properly filtering out undefined options and casting to the correct type. This follows the ICustomSearchSelectOption type definition correctly.
98-107: Improved page selection with CustomSearchSelect.The implementation replaces the previous menu component with CustomSearchSelect, providing a more consistent and user-friendly way to switch between pages. The component is properly configured with the necessary props.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx (5)
19-24: Type imports correctly support the new selection mechanism.The ICustomSearchSelectOption type import supports the new dropdown selection functionality, consistent with the pattern used in other header components.
26-26: UI component imports updated for new header features.The CustomSearchSelect component is now properly imported from @plane/ui for use in the view header.
150-165: Well-implemented view switcher options.The switcherOptions implementation follows the same pattern as in the pages header, creating a consistent user experience across different sections of the application. The mapping logic is clean and correctly handles null/undefined cases.
185-190: Consistent switcher implementation in breadcrumb.The CustomSearchSelect component is correctly implemented in the breadcrumb, using the same pattern as other headers for consistency across the application.
205-205: Header right item alignment improvement.Added "items-center" class to ensure proper vertical alignment of the right header elements.
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx (10)
3-3: Added useRef for parent reference.The addition of useRef is appropriate for creating a DOM reference that can be passed to the CycleQuickActions component.
21-26: Proper type imports for the header modifications.The ICustomSearchSelectOption import supports the new selection functionality, maintaining consistency with other header components.
28-28: Updated UI component imports.The CustomSearchSelect component is correctly imported alongside other necessary UI components.
31-32: Added imports for common components.The BreadcrumbLink and SwitcherLabel components are properly imported to support the new header functionality.
79-80: Added parentRef for CycleQuickActions.The parentRef is correctly implemented using useRef, providing a reference to the DOM element for the CycleQuickActions component.
170-186: Well-structured cycle switcher options.The switcherOptions implementation follows the same pattern as in other headers, providing a consistent user experience across different sections of the application.
187-188: Updated terminology from 'issues' to 'work items'.Good change to use workItemsCount instead of issuesCount for better clarity and consistency with the application's terminology.
231-253: Improved cycle selection with CustomSearchSelect.The implementation correctly uses CustomSearchSelect with proper configuration, including a count badge with tooltip for work items. The component follows the same pattern used in other headers.
328-329: Enhanced button styling for sidebar toggle.The updated styling for the sidebar toggle button improves visual consistency with other header elements.
331-331: Improved icon styling using conditional classes.Good use of the cn utility to conditionally apply styling to the PanelRight icon based on the sidebar state.
|
Pull Request Linked with Plane Work Items Comment Automatically Generated by Plane |
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (1)
1-111: Consider moving the header component to layout level.A previous review comment suggested "Move it to layout level." This might improve code organization and reusability across the application.
I notice there's a past review comment about moving this component to the layout level. Consider whether this refactoring should be part of the current PR or a separate task.
🧹 Nitpick comments (4)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/layout.tsx (1)
15-19: Consider adding error handling and loading states to SWR implementation.The SWR implementation is good for fetching page data conditionally based on URL parameters. However, it could be improved by handling error states and loading indicators.
- useSWR( - workspaceSlug && projectId ? `PROJECT_PAGES_${projectId}` : null, - workspaceSlug && projectId ? () => fetchPagesList(workspaceSlug.toString(), projectId.toString()) : null - ); + const { error, isLoading } = useSWR( + workspaceSlug && projectId ? `PROJECT_PAGES_${projectId}` : null, + workspaceSlug && projectId ? () => fetchPagesList(workspaceSlug.toString(), projectId.toString()) : null + ); + + // Optional: Handle error state + React.useEffect(() => { + if (error) console.error("Failed to fetch pages:", error); + }, [error]);web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (3)
39-39: Remove redundant null check.There are two identical null checks for the
pagevariable (lines 39 and 57). The second check is redundant since the function would already have returned ifpageis null at line 39.- if (!page) return null; const switcherOptions = projectPageIds .map((id) => { const _page = id === pageId ? page : getPageById(id); if (!_page) return; const pageLink = `/${workspaceSlug}/projects/${projectId}/pages/${_page.id}`; return { value: _page.id, query: _page.name, content: ( <Link href={pageLink} className="flex gap-2 items-center justify-between"> <SwitcherLabel logo_props={_page.logo_props} name={_page.name} LabelIcon={Layers} /> </Link> ), }; }) .filter((option) => option !== undefined) as ICustomSearchSelectOption[]; - if (!page) return null;Also applies to: 57-57
92-100: Empty onChange handler in CustomSearchSelect may cause confusion.The
onChangehandler for theCustomSearchSelectcomponent is empty (() => {}). While navigation is handled through theLinkcomponents within each option's content, having an empty handler might be confusing for other developers. Consider adding a comment explaining why it's empty or implementing proper onChange behavior if necessary.<CustomSearchSelect value={pageId} options={switcherOptions} label={<SwitcherLabel logo_props={page.logo_props} name={page.name} LabelIcon={Layers} />} - onChange={() => {}} + onChange={() => { + // Navigation is handled by Link components within each option + }} />
37-37: Validate projectId before using it as a parameter.The code directly uses
projectId?.toString()without validating if it's undefined. While the optional chaining provides some safety, consider adding a more explicit check or fallback value to avoid potential issues.- const projectPageIds = getCurrentProjectPageIds(projectId?.toString()); + const projectPageIds = getCurrentProjectPageIds(projectId?.toString() || "");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx(2 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/layout.tsx(1 hunks)web/core/components/cycles/analytics-sidebar/sidebar-header.tsx(0 hunks)web/core/components/cycles/quick-actions.tsx(2 hunks)web/core/components/modules/analytics-sidebar/root.tsx(3 hunks)web/core/components/modules/quick-actions.tsx(2 hunks)web/core/components/views/quick-actions.tsx(2 hunks)
💤 Files with no reviewable changes (1)
- web/core/components/cycles/analytics-sidebar/sidebar-header.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- web/core/components/modules/quick-actions.tsx
- web/core/components/cycles/quick-actions.tsx
- web/core/components/views/quick-actions.tsx
- web/core/components/modules/analytics-sidebar/root.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/layout.tsx (2)
web/ce/hooks/store/use-page-store.ts (1)
usePageStore(15-24)web/core/store/router.store.ts (2)
workspaceSlug(69-71)projectId(85-87)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (6)
web/ce/hooks/store/use-page.ts (1)
usePage(12-23)web/ce/hooks/store/use-page-store.ts (1)
usePageStore(15-24)web/core/store/router.store.ts (2)
projectId(85-87)workspaceSlug(69-71)web/core/components/common/switcher-label.tsx (1)
SwitcherLabel(13-27)packages/types/src/common.d.ts (1)
ICustomSearchSelectOption(30-36)packages/ui/src/dropdowns/custom-search-select.tsx (1)
CustomSearchSelect(14-218)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/layout.tsx (3)
4-5: Good addition of navigation and data fetching imports.The imports of
useParamsanduseSWRare appropriate for implementing the dynamic data fetching required in this component.
8-8: Good refactoring of import structure.The import from
@/plane-web/hooks/storenow correctly includes the necessaryEPageStoreTypeenum alongside theusePageStorehook.
13-14: Good implementation of parameter extraction and store access.The component now correctly extracts the route parameters using
useParams()and accesses the page store functionality through theusePageStorehook.web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (2)
3-20: The imports have been updated to support the new page switcher functionality.The changes in imports support the new page switcher functionality, adding necessary components like
Link,CustomSearchSelect, andSwitcherLabel, as well as the required typeICustomSearchSelectOption.
40-55: Good implementation of the page switcher options.The implementation effectively maps page IDs to selectable options with proper link navigation. The filtering of undefined values and type casting ensures type safety. This aligns well with the PR objective of adding a switcher for detail pages.
…6875) * chore: header revamp for cycles, modules, pages and views * chore: moved list fetch to layout level
Description
Added switcher for detail pages and quick actions menu to the header.
Type of Change
Screenshots and Media (if applicable)
Test Scenarios
References
WEB-3759
Summary by CodeRabbit
New Features
Refactor
Style