-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[WEB-4841] chore: calendar component migration UI to propel #7730
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: preview
Are you sure you want to change the base?
Conversation
Pull Request Linked with Plane Work Items
Comment Automatically Generated by Plane |
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughCalendar UI and DayPicker styles are moved from the UI package into a new Propel calendar module; web app imports updated to Changes
Sequence Diagram(s)sequenceDiagram
participant Web as apps/web components
participant Propel as @plane/propel/calendar
participant RDP as react-day-picker
Note over Web,Propel: Import-time routing after change
Web->>Propel: import { Calendar, Matcher, DateRange } from "@plane/propel/calendar"
Propel->>RDP: wraps and forwards props to DayPicker
Propel->>Propel: apply startMonth/endMonth, chevrons, classNames
Propel->>Web: rendered Calendar component (DayPicker output)
Note over UI,Web: Old flow (removed)
UI--xWeb: previously exported Calendar (deleted)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Pull Request Overview
This PR migrates the Calendar component from @plane/ui to @plane/propel package, consolidating dependencies and improving component organization.
- Moved Calendar component from @plane/ui to @plane/propel with react-day-picker dependency
- Updated all import statements across the web app to use the new calendar location
- Added comprehensive Storybook stories for the calendar component
Reviewed Changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
packages/ui/src/index.ts | Removed calendar export from UI package |
packages/ui/src/calendar.tsx | Deleted old calendar component implementation |
packages/propel/tsdown.config.ts | Added calendar to build configuration |
packages/propel/src/calendar/root.tsx | New calendar component implementation in propel |
packages/propel/src/calendar/index.ts | Calendar component exports and type re-exports |
packages/propel/src/calendar/calendar.stories.tsx | Comprehensive Storybook stories for calendar |
packages/propel/package.json | Added calendar export and react-day-picker dependency |
packages/propel/.storybook/preview.ts | Added calendar styles to Storybook |
apps/web/package.json | Removed react-day-picker dependency from web app |
apps/web/core/components/inbox/modals/snooze-issue-modal.tsx | Updated calendar import |
apps/web/core/components/dropdowns/date.tsx | Updated calendar and types import |
apps/web/core/components/dropdowns/date-range.tsx | Updated calendar and types import |
apps/web/core/components/core/filters/date-filter-modal.tsx | Updated calendar import |
apps/web/app/(all)/layout.tsx | Updated calendar styles import |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/web/core/components/core/filters/date-filter-modal.tsx (1)
47-50
: Bug: date2 watches date1, breaking range validation
date2
is incorrectly derived fromwatch("date1")
, soisInvalid
can’t detect inverted ranges.Apply this diff:
- const date1 = getDate(watch("date1")); - const date2 = getDate(watch("date1")); + const date1 = getDate(watch("date1")); + const date2 = getDate(watch("date2"));apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (1)
67-73
: Fix undefined close() call in onClick.close() is not defined in scope; call the provided handleClose() to dismiss the modal before confirming.
- <Button + <Button variant="primary" onClick={() => { - close(); + handleClose(); onConfirm(date); }} >
🧹 Nitpick comments (10)
packages/propel/package.json (1)
52-52
: Version ownership: pin vs. catalogHaving Propel own
[email protected]
is fine. If you prefer centralized versioning like other deps (catalog:
), consider moving this to the repo catalog for consistency. Optional.apps/web/core/components/core/filters/date-filter-modal.tsx (1)
97-110
: Minor: dedupe repeated Calendar classNamesThe
classNames.root
string is duplicated. Consider extracting to a constant to keep it DRY.+ const calendarRootClass = "border border-custom-border-200 p-3 rounded-md"; ... <Calendar - classNames={{ root: ` border border-custom-border-200 p-3 rounded-md` }} + classNames={{ root: calendarRootClass }} ... /> ... <Calendar - classNames={{ root: ` border border-custom-border-200 p-3 rounded-md` }} + classNames={{ root: calendarRootClass }} ... />Also applies to: 122-135
apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (1)
51-66
: Optional: avoid shadowing and redundant cloning.The onSelect parameter date shadows the state variable date, and selected/defaultMonth re-wrap date with new Date(..) unnecessarily. Not a bug, but minor cleanup possible.
- onSelect={(date) => { - if (!date) return; - setDate(date); + onSelect={(d) => { + if (!d) return; + setDate(d); }} - selected={date ? new Date(date) : undefined} - defaultMonth={date ? new Date(date) : undefined} + selected={date ?? undefined} + defaultMonth={date ?? undefined}packages/propel/src/calendar/root.tsx (2)
21-33
: Tighten Chevron override (destructure orientation, clearer props).Readability: destructure orientation directly and pass the rest explicitly.
- components={{ - Chevron: ({ className, ...props }) => ( - <ChevronLeft - className={cn( - "size-4", - { "rotate-180": props.orientation === "right", "-rotate-90": props.orientation === "down" }, - className - )} - {...props} - /> - ), - }} + components={{ + Chevron: ({ className, orientation, ...rest }) => ( + <ChevronLeft + className={cn( + "size-4", + { "rotate-180": orientation === "right", "-rotate-90": orientation === "down" }, + className + )} + {...rest} + /> + ), + }}
19-35
: Remove redundant prop and clarify end-of-window var name.
- weekStartsOn is already included via {...props}; the explicit prop is redundant.
- Rename thirtyYearsFromNowFirstDay to thirtyYearsFromNowLastDay to reflect Dec 31.
export const Calendar = ({ className, showOutsideDays = true, ...props }: CalendarProps) => { const currentYear = new Date().getFullYear(); const thirtyYearsAgoFirstDay = new Date(currentYear - 30, 0, 1); - const thirtyYearsFromNowFirstDay = new Date(currentYear + 30, 11, 31); + const thirtyYearsFromNowLastDay = new Date(currentYear + 30, 11, 31); return ( <DayPicker showOutsideDays={showOutsideDays} className={cn("p-3", className)} - weekStartsOn={props.weekStartsOn} components={{ Chevron: ({ className, ...props }) => ( <ChevronLeft className={cn( "size-4", { "rotate-180": props.orientation === "right", "-rotate-90": props.orientation === "down" }, className )} {...props} /> ), }} startMonth={thirtyYearsAgoFirstDay} - endMonth={thirtyYearsFromNowFirstDay} + endMonth={thirtyYearsFromNowLastDay} {...props} /> ); }packages/propel/src/calendar/calendar.stories.tsx (5)
1-4
: Import from the public barrel and pull in reusable typesStories should exercise the public API and reuse exported types.
-import { Calendar } from "./root"; +import { Calendar, type DateRange, type Matcher } from ".";
41-44
: Use the DateRange type for stronger typingAligns with the Calendar/DayPicker API and simplifies future refactors.
- const [dateRange, setDateRange] = useState<{ from?: Date; to?: Date }>({ + const [dateRange, setDateRange] = useState<DateRange | undefined>({ from: new Date(), to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now });
73-75
: Guard onSelect against undefined in multiple modeDayPicker may call onSelect with undefined; keep state consistent.
- onSelect={setDates} + onSelect={(v) => setDates(v ?? [])}
86-90
: Type disabledDays for better safety and editor helpAnnotate as Matcher[] to match DayPicker’s matcher API.
- const disabledDays = [ + const disabledDays: Matcher[] = [ { dayOfWeek: [0, 6] }, // Sunday and Saturday new Date(2024, 4, 10), // May 10, 2024 ];
21-143
: Optional: make stories time-stableDirect new Date() calls can cause flaky visuals over time. Consider a fixed “today” (e.g., via a const or Storybook global/arg) to stabilize snapshots.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
apps/web/app/(all)/layout.tsx
(1 hunks)apps/web/core/components/core/filters/date-filter-modal.tsx
(1 hunks)apps/web/core/components/dropdowns/date-range.tsx
(1 hunks)apps/web/core/components/dropdowns/date.tsx
(1 hunks)apps/web/core/components/inbox/modals/snooze-issue-modal.tsx
(1 hunks)apps/web/package.json
(0 hunks)packages/propel/.storybook/preview.ts
(1 hunks)packages/propel/package.json
(3 hunks)packages/propel/src/calendar/calendar.stories.tsx
(1 hunks)packages/propel/src/calendar/index.ts
(1 hunks)packages/propel/src/calendar/root.tsx
(1 hunks)packages/propel/tsdown.config.ts
(1 hunks)packages/ui/src/calendar.tsx
(0 hunks)packages/ui/src/index.ts
(0 hunks)
💤 Files with no reviewable changes (3)
- packages/ui/src/index.ts
- apps/web/package.json
- packages/ui/src/calendar.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-04T16:22:44.344Z
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
Applied to files:
packages/propel/.storybook/preview.ts
🧬 Code graph analysis (1)
packages/propel/src/calendar/calendar.stories.tsx (1)
packages/propel/src/calendar/root.tsx (1)
Calendar
(11-38)
🪛 GitHub Check: Build and lint web apps
packages/propel/src/calendar/calendar.stories.tsx
[failure] 5-5:
An interface declaring no members is equivalent to its supertype
⏰ 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). (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (12)
apps/web/app/(all)/layout.tsx (1)
8-8
: No lingering old stylesheet references; migration complete
Verified there are no imports or files for the old react-day-picker.css and all consumers now import from @plane/propel/styles/react-day-picker.packages/propel/.storybook/preview.ts (1)
3-3
: Storybook CSS import is appropriate for local devImporting from src keeps HMR tight for Storybook. No change requested.
packages/propel/package.json (2)
21-34
: Exports and copy step verified
Calendar and react-day-picker CSS subpath exports match their dist paths and tsdown copiessrc/styles
as configured, so importing the CSS subpath will work.
41-57
: Confirm noreact-day-picker
usage in apps/web
No references found inapps/web/package.json
or code imports/requires; safe to merge.packages/propel/tsdown.config.ts (2)
7-8
: Calendar entry added to build surface—LGTMIncluding
src/calendar/index.ts
ensures types and JS ship properly.
27-28
: Verify CSS export path Ensure that after running the build,react-day-picker.css
is located atpackages/propel/dist/styles/react-day-picker.css
.apps/web/core/components/core/filters/date-filter-modal.tsx (1)
8-9
: Import migration to Propel calendar looks correctDecouples the app from UI’s calendar. Button import separation is fine.
apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (2)
7-8
: Calendar import migration looks good.Importing Calendar from @plane/propel/calendar and keeping Button from @plane/ui aligns with the package split.
1-85
: Resolve DayPicker style and dependency checks: CSS import from @plane/propel/styles/react-day-picker is present, no direct react-day-picker imports or Calendar from @plane/ui remain, and the react-day-picker dependency has been moved to packages/propel.packages/propel/src/calendar/index.ts (1)
1-2
: Barrel and type re-exports look correct.Re-exporting Calendar and the Matcher/DateRange types from one place simplifies app imports.
apps/web/core/components/dropdowns/date-range.tsx (1)
12-13
: Good consolidation of imports via Propel.Pulling Calendar, DateRange, and Matcher from @plane/propel/calendar removes the app’s direct coupling to react-day-picker.
apps/web/core/components/dropdowns/date.tsx (1)
8-9
: Import migration looks good.Using Calendar and Matcher from @plane/propel/calendar with ComboDropDown from @plane/ui matches the new split.
Description
This PR includes the following changes:
Type of Change
Media
Summary by CodeRabbit