* [#559] added delegated calendars in user selector
* [#559] selector for calendar display delegated and personal separatly
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
Deduplicate resolveTimezone, resolveTimezoneId, convertEventDateTimeToISO,
and getTimezoneOffset into a single canonical module, removing copies from
EventApi, eventUtils, TimezoneSelector, EventUpdateModal, and calendarUtils.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- When dragging from allday slot: open normal mode with allday checked, show start date and end date
- When dragging from week/month view grid: open normal mode with allday checked, show 4 fields (start date, start time, end date, end time)
- Update DateTimeFields logic to support displaying time fields when allday=true and hasEndDateChanged=true for multiple days events
Add setHasEndDateChanged(false) to resetAllStateToDefault function to prevent stale state when:
- User creates multi-day event from grid (sets hasEndDateChanged = true)
- Closes the modal
- Opens modal again for a single-day event
This ensures hasEndDateChanged is properly reset to false when modal is closed or reset.
Fix drag and drop logic: keep allday=false when dragging from week view
- Remove setAllDay(true) when dragging multiple days from week view grid
- Keep allday=false to show time fields for week view drag scenarios
- Add comprehensive test cases for drag and drop scenarios
- Test cases cover allday slot and week view drag scenarios
- Prevent regressions with test coverage for display logic
- Replace default TimePicker field with custom EditableTimeField
- Allow free typing with multiple formats (HH:mm, HHmm, H, etc.)
- Show dropdown on click while maintaining typing capability
- Center-align time input text
* [#337] added timezone loading from backend
* [#337] changed data structure to allow patching timezone while keeping other datetime params value
* [#337] fixed gap, event create modale sync with settings and added checkbox
* [#337] isBrowserDefaultTimezone is set to true when API return null timezone
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
- Add temp storage utility (eventFormTempStorage.ts) to save/restore form data
- Implement error handling: close modal immediately, reopen on API failure with saved data
- Add event listeners in Calendar.tsx and EventDisplayPreview.tsx to reopen modals on error
- Fix calendar change logic in EventUpdateModal: use oldCalendar for update before move
- Update all test mocks to support .unwrap() method for Redux thunks
- Add sessionStorage.clear() in test beforeEach hooks
- Fix test timing issues with act() wrappers and increased timeouts
- Mock putEventAsync in TempUpdate test to ensure updateTempCalendar is called
- Fix update modal not reopening when API fails for recurring events (solo/all)
- Move update modal reopen logic from EventDisplayPreview to Calendar.tsx
- Use sessionStorage to persist update modal info across component unmounts
- Handle typeOfAction matching for recurring events (undefined vs solo/all)
- Fix error handling in updateEventInstanceAsync and updateSeriesAsync
- Ensure all API failures properly dispatch eventModalError event
- Fix timezone field display in event modals to show original timezone from server
- Fix formatDateToICal to use moment.utc(date).tz(timezone) for correct UTC instant preservation
- Fix parseCalendarEvent to convert event.start/end to ISO UTC strings after parsing
- Fix eventToFullCalendarFormat to ensure event times are ISO UTC before passing to FullCalendar
- Fix getEvent to normalize event.start/end to ISO UTC strings
- Ensure event.timezone is always set (defaults to Etc/UTC if not detected)
- Update eventUtils.test.ts to match new timezone conversion logic
- Fix event time shift issue on calendar grid display
This ensures:
- Events display in correct time slots on calendar grid
- Event times are correctly converted between timezones
- Original timezone from server is preserved and displayed
- All event times are stored as ISO UTC strings internally
* refactor: eliminate datetime format detection code duplication
- Add constants for datetime format strings and magic number (DATETIME_WITH_SECONDS_LENGTH, DATETIME_FORMAT_WITH_SECONDS, DATETIME_FORMAT_WITHOUT_SECONDS)
- Create shared detectDateTimeFormat() function to replace duplicated format detection logic
- Refactor convertFormDateTimeToISO, convertEventDateTimeToISO, and convertDateTimeStringToISO to use shared helper
- Add console.warn logging when invalid datetime is encountered (addresses silent fallback issue)
- Add comprehensive test coverage for dateTimeHelpers with full test suite
- Change 'Start Date' label to 'Date' when only single date field is visible in normal mode
- Fix all-day slot display: show correct start/end dates for single click and multi-day drag
- Update API save logic: add +1 day to end date for all-day events (API requirement)
- Migrate from moment to dayjs for date handling with AdapterDayjs
- Remove manual date clamping logic - MUI/dayjs handles invalid dates automatically
- Add validation guard to prevent invalid dates from clearing field values
- Update test case to match new all-day event API behavior
- Add long date format display (Monday, April 23, 2024)
- Use 24h time format
- Show/hide time fields based on all-day state
- Remove auto-update of end date when start date changes
- Fix validation for all-day events
- Auto-expand for multi-day events
- Set default time when toggling off all-day from all-day slot
- Replace single datetime-local field with 4 separate fields:
- Add helper functions:
* splitDateTime(): Split datetime string into date and time parts
* combineDateTime(): Combine date and time into datetime string
- Implement internal state management:
* startDate, startTime, endDate, endTime internal states
* Sync effects to update internal states from start/end props
* Change handlers for each field that combine values and call parent handlers
- Fix test cases:
* Update EventModal.test.tsx, EventUpdateModal.test.tsx to use new field labels
* Change from 'Start'/'End' to 'Start Date'/'Start Time'/'End Time'/'End Date'
* refactor: migrate EventModal to use shared EventFormFields component
* feat: add form validation for event create/update
- Validate title is required
- Validate end datetime must be after start datetime
- Disable save button when form is invalid
- Show error messages below invalid fields with red highlight (MUI)
- Title validation in create mode only shows error after field is touched
- Track touched state to avoid showing errors on initial load
* feat: improve event modal UX with auto-focus and default times
- Auto-focus title field when opening create/update event modal
- Set default datetime when creating event without selecting range:
* Start time = current time + 1 hour (rounded to :00)
* End time = start time + 1 hour
- Applied duplicate event to display datetime from original event
- Fix logic to detect empty event object vs valid event with uid
* fix: improve validation UX and add required field indicator
- Only show validation errors when modal is open (isOpen check)
- Add red asterisk (*) to Title label to indicate required field
- Prevent validation error flash when closing modal
- Fix TypeScript errors in EventUpdateModal
- Keep validation behavior: only show error after user types and deletes
* feat: auto-focus title field when toggling between normal and extended mode in event modal
* update: only validation when click on save button
* fix: prevent form data loss and validation errors in event modals
Fixes:
1. Form fields no longer clear when changing start/end dates
2. Extended mode stays active when modifying dates
3. No validation errors shown after successful save
- Resolve timezone alias to main timezone in TimezoneSelector before passing to TimezoneAutocomplete
- Resolve timezone in EventModal useState initialization to ensure correct timezone display
- Sync resolved timezone when modal opens or Redux timezone changes
- Ensure timezone is always resolved in resetAllStateToDefault callback
- Fix issue where TimezoneAutocomplete doesn't show correct timezone on first load
- Create new TimezoneAutocomplete component for shared timezone selection logic
- Update TimezoneSelector to use the new component
- Replace inline Autocomplete in EventFormFields with TimezoneAutocomplete
- Replace inline Autocomplete in EventModal with TimezoneAutocomplete
- Reduce code duplication and improve maintainability
- Replace timezone Select field with Autocomplete in EventModal and EventFormFields
- Add search functionality for timezones with text input
- Add timezone icon to match PeopleSearch component style
- Remove 'Mark as important' checkbox from EventModal (re showup when rebase)
- Remove gap space in description when desc field show up
- Add expand and close icons to ResponsiveDialog header in normal mode
- Change 'Show More' button to 'More options' with Add icon
- Hide Cancel button in normal mode, show only in extended mode
- Add showHeaderActions prop to ResponsiveDialog for UI control
- Preserve EventDisplayPreview modal with old UI (no header icons)
- Update all affected test cases to match new UI behavior
- Fix infinite loop in EventModal useEffect by using useRef for userPersonnalCalendars
- Fix weekStart calculation in putEventAsync to use Monday as first day (consistent with FullCalendar firstDay=1)
- Add computeWeekRange utility function for consistent week calculations
- Improve state reset logic when closing EventModal popup
- Ensure repeat checkbox state is properly reset to prevent stale repetition data
- Replace 'Meeting link generated' text with 'Join Visio conference' button
- Button opens video conference link in new tab when clicked
- Use contained variant styling to match Save button appearance
- Maintain copy and delete functionality for meeting links
- Fix calendarUtils.ts null safety for calendars[id] access
- Update video conference link to be added on line 2 instead of line 3
- Update regex in handleDeleteVideoConference to match new format
- Update all test cases for videoConferenceUtils to match new format
- Add null checks in updateCalsDetails function
- Add video conference utility functions for generating random meeting IDs
- Implement video meeting button with camera icon in EventModal
- Add copy and delete functionality with IconButton components
- Support X-OPENPAAS-VIDEOCONFERENCE field in CalendarEvent type
- Handle state management for editing events with/without video conference
- Add meeting link footer to event description
- Include comprehensive test suite for video conference utilities
Features:
- Generate random meeting links (format: xxx-xxxx-xxx)
- Copy meeting link to clipboard
- Remove video conference from events
- Proper state sync when editing different events
- Integration with existing JCal/ICS conversion
- Update RepeatEvent.test.tsx to use correct selectors and text matching
- Update EventDisplay.test.tsx to use 'Notification' instead of 'Alarm'
- Update EventModal.test.tsx to use new label names and fix description input tests
- Update Calendar.test.tsx to use new placeholder text 'Start typing a name or email'
- Fix EventDisplay.tsx to use 'Notification' label consistently
- Rename 'Alarm' to 'Notification' for better clarity
- Rename 'Attendees' to 'Participants' with updated placeholder text
- Replace 'Visibility' dropdown with 'Visible to' toggle buttons (All/Participants)
- Remove CONFIDENTIAL option, keep only PUBLIC and PRIVATE
- Add icons (PublicIcon/LockIcon) with fixed sizing for toggle buttons
- Rename 'Show as' to 'Show me as'
- Fix ResponsiveDialog scroll bar positioning in expanded mode
- Update PeopleSearch placeholder to 'Start typing a name or email'
Implemented a new ResponsiveDialog component and redesigned EventModal
with better UX for both normal and extended modes.
New Features:
- Created reusable ResponsiveDialog component (src/components/Dialog/)
* Normal mode: 685px centered popup
* Extended mode: fullscreen with 90px header preservation
* Auto spacing via MUI Stack (16px normal, 24px extended)
* Back arrow navigation in extended mode
* No backdrop/shadow in extended mode for seamless integration
* Configurable props for all dimensions and behaviors
EventModal Improvements:
- Replaced native checkbox with MUI Checkbox component
- Migrated from Popover to ResponsiveDialog
- Reorganized field layout
=> Comprehensive documentation in Dialog/README.md
Note: RepeatEvent integration tests need additional refactoring (tracked separately)
* feat: prepare project for cozy-ui migration
Build Configuration
- Add Stylus support via @rsbuild/plugin-stylus
- Add SVGR support via @rsbuild/plugin-svgr
- Update rsbuild.config.ts with custom configuration
- Add historyApiFallback for SPA routing
ESLint Configuration
- Create .eslintrc.json with react-app configuration
- Remove eslintConfig from package.json
CSS to Stylus Migration
Convert all 5 CSS files to Stylus (.styl) format:
- src/App.css to src/App.styl
- src/index.css to src/index.styl
- src/components/Calendar/Calendar.css to src/components/Calendar/Calendar.styl
- src/components/Calendar/CustomCalendar.css to src/components/Calendar/CustomCalendar.styl
- src/components/Menubar/Menubar.css to src/components/Menubar/Menubar.styl
- Update all imports from .css to .styl
- Preserve all styling rules and values
MUI Styling Cleanup
- Replace all MUI sx props with standard style props across 15+ components
- Convert MUI spacing units (mr: 2 to marginRight: 16px)
- Convert MUI shorthand props (p: 2 to padding: 16px, mb: 1 to marginBottom: 8px)
- Remove MUI-specific syntax (&.Mui-checked selectors)
- Maintain exact visual appearance
FullCalendar Fixes
- Comment out problematic CSS rule in CustomCalendar.styl
- Fix display issues with timegrid slot labels
Files Modified
- Config: rsbuild.config.ts, .eslintrc.json, package.json
- Styling: 5 CSS to Stylus conversions, 15+ component sx to style updates
- Components: All components using MUI sx props updated
Development Workflow
- Continue using existing development commands
- Stylus files are now the source of truth for styling
- MUI components work with standard style props
- ESLint uses familiar react-app rules
Dependencies Added
- @rsbuild/plugin-stylus
- @rsbuild/plugin-svgr
- Sync calendar view state between Calendar and Menubar components
- Fix Redux serialization errors by using string dates instead of Date objects
- Add null checks for eventResize handler to prevent undefined errors
- Implement dynamic slot label dimming near current time indicator
- Slot labels fade to opacity 0.2 when now indicator is within 15 minutes
- Add smooth CSS transitions for better user experience
- Handle edge cases around midnight for proper time calculation
- Update slot label visibility on view changes and time updates
* [123] added people search in left side bar
* [#123] added toggle temp calendars
* [#123] added tests]
* fixup! [123] added people search in left side bar
* fixup! [#123] added toggle temp calendars
* [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] fixed event creation on Enter
* [#123] added color diff for temp calendars
* fixup! [#123] fixed event creation on Enter
* fixup! [#123] added tests]
* fixup! [#123] added toggle temp calendars
---------
Co-authored-by: Camille Moussu <cmoussu@linagora.com>