Commit Graph

55 Commits

Author SHA1 Message Date
Camille Moussu 2f2ee369fc [#525] adopted twake-i18n (#404)
* [#525] adopted twake-i18n 

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-12-09 11:10:44 +01:00
Camille Moussu d8c931e02e [#317] improved event error management + test (#358)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-25 15:46:30 +01:00
lenhanphung 9151ff5563 fix: preserve form data on API error and fix test cases (#338)
- 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
2025-11-25 15:30:58 +01:00
lenhanphung 25dc016688 Enhance UI: #355 Remove labels, update buttons, icons, and styles (#356)
Co-authored-by: Lê Nhân Phụng <lenhanphung@Phung-Mac-M4.local>
2025-11-25 11:17:24 +01:00
Camille Moussu 25078c783e [#285] added duration enforcement to date and time in dateTimeFields (#343)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-25 11:16:45 +01:00
Camille Moussu 6b6c140854 #335 missing translations (#353)
* added missing import for date field translations

* added missing keys in russian locale

* added missing keys in vietnamese file

* added missing locales import for calendar localisation

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-24 16:44:38 +01:00
lenhanphung bff1af31bd Fix: Preserve timezone used in create and update modal (#301)
- 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
2025-11-20 09:32:15 +01:00
Camille Moussu ca2e8a479a [#309] homogenized add add Desc button (#345)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-19 15:23:37 +01:00
Camille Moussu 1bc9b0c160 [#268] changed timezone offset calculation (#306)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-14 08:52:02 +01:00
Camille Moussu 3c26a81773 [#296] removed old condition that is no longer needed (#305)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-12 20:57:16 +01:00
Camille Moussu 1bb24b2672 [#297] added missing translation (#303)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-12 20:47:55 +01:00
Camille Moussu f886846a2b [#265] prefills title + trad + test (#293)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-12 20:42:05 +01:00
Camille Moussu ddc651f8ca [#230] added toast to copy visio link (#286)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-07 08:11:11 +01:00
Camille Moussu 36bc027d6d [#82] added cozy-ui for internationnalisation (#267)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-06 15:46:58 +01:00
lenhanphung c1f37e3ebd feat: improve date/time fields UI and logic
- 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
2025-11-05 10:25:41 +01:00
lenhanphung 41b4c41215 Event form UX improvements:
- 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
2025-11-05 10:25:41 +01:00
lenhanphung 61358c081a feat(ui): replace end date field with '...' button toggle
- Hide end date by default; reveal via '...' button in both modes
- Keep state/validation/API logic unchanged
- Normalize labels to use MUI TextField labels across modes
- Align button with fields; constrain widths for expanded mode
2025-11-05 10:25:41 +01:00
lenhanphung 5078128e10 test: fix test cases for MUI DatePicker and TimePicker migration
- Add data-testid attributes to DatePicker and TimePicker components in DateTimeFields
- Update test queries from getByLabelText to getByTestId for date/time inputs
- Fix assertions to use toHaveAttribute instead of toHaveValue for MUI pickers
- Add data-testid to occurrences-input in EventRepeat component
- Update RepeatEvent test to use data-testid for occurrences input
- Fix radio button queries using getAllByLabelText with type filter
2025-11-05 10:25:41 +01:00
lenhanphung 3c75a7e82e feat: replace TextField with MUI DatePicker and TimePicker in DateTimeFields
- Replace native HTML date/time inputs with MUI X Date Pickers components
- Add DatePicker for start/end dates
- Add TimePicker for start/end times
2025-11-05 10:25:41 +01:00
lenhanphung 01f79553c0 refactor: Split EventFormFields.tsx into smaller modules
- Extract helper functions to utils/dateTimeHelpers.ts and utils/dateTimeFormatters.ts
- Extract validation logic to utils/formValidation.ts
- Extract FieldWithLabel component to components/FieldWithLabel.tsx
- Extract DateTimeFields component to components/DateTimeFields.tsx
- Extract all-day toggle logic to hooks/useAllDayToggle.ts
- Update imports in EventModal.tsx, EventUpdateModal.tsx, EventDisplay.tsx, eventHandlers.ts
- Maintain all existing functionality without breaking changes
2025-11-05 10:25:41 +01:00
lenhanphung 701f2f2b71 feat: Split datetime fields
- 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'
2025-11-05 10:25:41 +01:00
Camille Moussu 838262fde3 [#277] fixed conditions to prevent blink in compact event chips (#280)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-04 14:18:55 +01:00
Camille Moussu 2cf20e9655 [#269] fix selection error (#273)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-11-03 14:35:05 +01:00
Camille Moussu ec7230fa94 [#189] added custom event chip (#262)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-10-31 11:50:22 +01:00
Camille Moussu 39d8085766 [#205] added calendar list component (#258)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-10-31 04:44:54 +01:00
lenhanphung 4774e78543 feat: Update Event Preview Modal UI with custom MUI theme (#240)
- Add custom MUI theme
- Update ResponsiveDialog with actionsBorderTop prop for modal footer border
- Redesign EventDisplayPreview modal with improved typography and spacing
- Replace ButtonGroup with individual RSVP buttons (Accept/Maybe/Decline)
- Add pill-shaped buttons for RSVP actions
- Ensure backward compatibility with existing modals
2025-10-27 06:23:42 +01:00
lenhanphung 8681e88390 fix: preserve recurrence exceptions when RSVP to recurring events (#234)
When an attendee accepts/rejects/tentative a recurring event with
exceptions, only update the PARTSTAT without removing exception events.

Add removeOverrides: false parameter to updateSeriesAsync call in
handleRSVP function to preserve all recurrence exceptions.

Fixes: Recurrence exceptions being deleted when accepting/rejecting
all events in a recurring series

* fix: update PARTSTAT on all VEVENTs when RSVP to recurring events

When an attendee accepts/rejects/tentative a recurring event with exceptions,
update PARTSTAT on ALL VEVENTs (master + exceptions) to reflect the correct
attendance status across the entire series.

Changes:
- Add updateSeriesPartstat() in EventApi.ts to update PARTSTAT on all VEVENTs
- Update handleRSVP() to use new function instead of updateSeriesAsync
- Preserve exception times while updating PARTSTAT consistently
- Update test to verify new function is called correctly

Fixes: Exception events not accepting when user chooses 'Accept all events'
2025-10-23 05:36:34 +02:00
lenhanphung 1c8826facc Form validation for event create/update (#218)
* 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
2025-10-22 11:52:38 +02:00
Camille Moussu e99c56f03f Handle long descriptions (#228)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-10-21 12:17:36 +02:00
lenhanphung 6421f53a8d refactor: extract reusable TimezoneAutocomplete component
- 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
2025-10-20 07:22:00 +02:00
lenhanphung 2ab7c448bf refactor: replace timezone Select with Autocomplete
- 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
2025-10-20 07:22:00 +02:00
Camille Moussu f278caf041 [#168] changed temp calendar reload to reload only thoses that are impacted 2025-10-17 11:26:50 +02:00
Camille Moussu 29f984b347 [#168] added refresh to temp calendars when updating 2025-10-17 11:26:50 +02:00
lenhanphung 5017c1bd6b fix: improve event editing UX and allday toggle behavior
- Fix allday toggle: when unchecking allday, set end date = start date with rounded time (30min intervals)
- Fix ResponsiveDialog CSS: set height only for expanded mode, remove maxHeight from normal mode
- Show repeat info when editing solo instance of recurring event (checkbox checked and disabled)
- Clear old event UI when updating recurring event allday status
2025-10-15 08:29:28 +02:00
lenhanphung 40f0179be6 fix: directly delete recurring events when converting to non-recurring
- Use direct API call to delete recurring events instead of going through Redux store
- Construct event URL directly for more reliable deletion
- Add error handling and small delay to ensure complete deletion
- Clean up all instances from store after deletion
2025-10-15 08:29:28 +02:00
lenhanphung 474ff22cab fix: properly handle recurring events in EventUpdateModal
- Fix handling of solo vs. all event updates for recurring events
- Add calendar refresh for update all events
- Disable repeat option when editing a single occurrence (solo mode)
- Fix event recurrence editing in modals to match main branch
- Properly link EventDisplayPreview with EventUpdateModal for typeOfAction
2025-10-15 08:29:28 +02:00
lenhanphung 601c75db33 feat: integrate main's EventDisplayPreview UI with EventUpdateModal
1. Replace old EventDisplayPreview with main's new Figma UI
   - Use ResponsiveDialog instead of Popover
   - Keep file at features/Events/ location (not components/Event/)
   - Integrate InfoRow, EditModeDialog components from main
   - Fix all imports to work with new location

2. Add EventUpdateModal integration
   - Edit icon now opens EventUpdateModal instead of EventDisplayModal
   - EventUpdateModal uses shared EventFormFields component

3. Fix imports and exports
   - Use default import for ResponsiveDialog
   - Use named import for EditModeDialog
   - Fix anchorPosition to be optional with default value

4. Performance improvement
   - Open EventUpdateModal immediately without waiting for API
   - Let modal fetch fresh data in background via useEffect

5. Fix Checkbox styling warning
   - Use sx prop instead of style for nested MUI selectors
   - Fix 'Unsupported style property &.Mui-checked' console warning
2025-10-15 08:29:28 +02:00
lenhanphung 64393bf161 fix: preserve original timezone when reopening event update modal
- Add formatDateTimeInTimezone() helper to format dates in event's original timezone
- Fix EventUpdateModal to display event times in original timezone instead of browser timezone
- Fix EventModal (duplicate event) with same timezone handling
- Update EventDisplay tests to use flexible date pattern
2025-10-15 08:29:28 +02:00
lenhanphung 80c1babb7f refactor: remove 'mark as important' field and clean up console.log statements
- Remove 'important' field from EventFormFields component and all event modals
- Remove all console.log statements from event create/update flow
- Fix import issues and type compatibility in EventModal
2025-10-15 08:29:28 +02:00
lenhanphung 42c953ccf9 feat(events): align Update modal with Create; extract shared form fields
- ux: close Update modal immediately on Save; run API in background
- fix: remove stale single-instance when converting to repeating
- test: adjust EventDisplay expectations
- refactor: share form via components/Event/EventFormFields (used by Create/Update)
2025-10-15 08:29:28 +02:00
Camille Moussu 770257c03b [#154] added timezone component to change timezone of calendar (#207)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-10-14 15:25:28 +02:00
Camille Moussu c86db8fa49 refactor recurring event modification (#173) 2025-10-07 18:16:00 +02:00
Camille Moussu 3f8f3eff23 [#162] changed preview modal looks to follow figma (#163)
Co-authored-by: Camille Moussu <cmoussu@linagora.com>
2025-10-07 11:20:09 +02:00
lenhanphung 4eb2c86771 fix: update test cases to match new UI labels
- 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
2025-10-02 14:19:05 +07:00
lenhanphung 3261479874 refactor: improve EventModal UI labels and visibility controls
- 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'
2025-10-02 14:19:05 +07:00
lenhanphung 3870bceb6d feat: prepare project for cozy-ui migration (#157)
* 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
2025-10-01 17:31:18 +02:00
lenhanphung b9d7a8fa6b feat: enhance calendar with view sync, Redux fixes, and dynamic slot label dimming
- 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
2025-09-25 17:12:07 +07:00
Camille Moussu 8f2277b278 [#72] added duplicate button and fixed tests broken by new interaction between components 2025-09-11 18:22:11 +02:00
Camille Moussu 37ab51784c [#77] added event start day selected by default when repetition is set to weekly 2025-09-08 11:23:24 +02:00
Camille Moussu 2f071303de [#77] fixed delete refresh issue and added more tests 2025-09-05 16:41:05 +02:00