11import { ObjectItem } from "mendix" ;
2- import { DateLocalizer , Formats , ViewsProps } from "react-big-calendar" ;
2+ import { DateLocalizer , Formats , View , ViewsProps } from "react-big-calendar" ;
33import { CustomWeekController } from "./CustomWeekController" ;
44import { CalendarContainerProps } from "../../typings/CalendarProps" ;
55import { createConfigurableToolbar , CustomToolbar , ResolvedToolbarItem } from "../components/Toolbar" ;
@@ -8,7 +8,7 @@ import { CalendarEvent, DragAndDropCalendarProps } from "../utils/typings";
88
99export class CalendarPropsBuilder {
1010 private visibleDays : Set < number > ;
11- private defaultView : "month" | "week" | "work_week" | "day" | "agenda" ;
11+ private defaultView : View ;
1212 private isCustomView : boolean ;
1313 private events : CalendarEvent [ ] ;
1414 private minTime : Date ;
@@ -48,8 +48,7 @@ export class CalendarPropsBuilder {
4848 this . defaultDate = props . startDateAttribute ?. value ;
4949 }
5050
51- build ( localizer : DateLocalizer , culture : string ) : DragAndDropCalendarProps < CalendarEvent > {
52- const formats = this . buildFormats ( localizer ) ;
51+ build ( localizer : DateLocalizer , culture : string , activeView ?: View ) : DragAndDropCalendarProps < CalendarEvent > {
5352 const views = this . buildVisibleViews ( ) ;
5453 const toolbar =
5554 this . isCustomView && this . toolbarItems && this . toolbarItems . length > 0
@@ -62,15 +61,22 @@ export class CalendarPropsBuilder {
6261 // Ensure defaultView is actually enabled in views, otherwise pick the first enabled view
6362 const enabledViews = Object . entries ( views )
6463 . filter ( ( [ _ , enabled ] ) => enabled !== false )
65- . map ( ( [ view ] ) => view as "day" | "week" | "work_week" | "month" | "agenda" ) ;
64+ . map ( ( [ view ] ) => view as View ) ;
6665 const safeDefaultView = enabledViews . includes ( this . defaultView ) ? this . defaultView : enabledViews [ 0 ] ;
6766
67+ // The view RBC is actually showing right now. Falls back to safeDefaultView when the
68+ // caller hasn't told us yet (first render) or the reported view is no longer enabled.
69+ const effectiveView = activeView && enabledViews . includes ( activeView ) ? activeView : safeDefaultView ;
70+
71+ const formats = this . buildFormats ( localizer , effectiveView ) ;
72+
6873 return {
6974 localizer,
7075 culture,
7176 components : {
7277 toolbar
7378 } ,
79+ view : effectiveView ,
7480 defaultView : safeDefaultView ,
7581 messages : this . buildMessages ( workWeekCaption ) ,
7682 events : this . events ,
@@ -141,7 +147,10 @@ export class CalendarPropsBuilder {
141147 }
142148 }
143149
144- private buildFormats ( _localizer : DateLocalizer ) : Formats {
150+ private buildFormats (
151+ _localizer : DateLocalizer ,
152+ activeView : "day" | "week" | "work_week" | "month" | "agenda"
153+ ) : Formats {
145154 const formats : Formats = { } ;
146155
147156 const timePattern = this . getSafeTimePattern ( ) ;
@@ -207,17 +216,8 @@ export class CalendarPropsBuilder {
207216 loc . format ( date , dayHeaderPattern , culture ) ;
208217 }
209218
210- const weekHeaderPattern = getPattern (
211- byType . get ( "week" ) ?. customViewHeaderDayFormat || byType . get ( "work_week" ) ?. customViewHeaderDayFormat
212- ) ;
213- if ( weekHeaderPattern ) {
214- formats . dayRangeHeaderFormat = (
215- range : { start : Date ; end : Date } ,
216- culture : string ,
217- loc : DateLocalizer
218- ) =>
219- `${ loc . format ( range . start , weekHeaderPattern , culture ) } – ${ loc . format ( range . end , weekHeaderPattern , culture ) } ` ;
220- }
219+ const weekOwnPattern = getPattern ( byType . get ( "week" ) ?. customViewHeaderDayFormat ) ;
220+ const workWeekOwnPattern = getPattern ( byType . get ( "work_week" ) ?. customViewHeaderDayFormat ) ;
221221
222222 const monthHeaderPattern = getPattern ( byType . get ( "month" ) ?. customViewHeaderDayFormat ) ;
223223 if ( monthHeaderPattern ) {
@@ -226,33 +226,47 @@ export class CalendarPropsBuilder {
226226 }
227227
228228 // Per-column headers — distinct from the toolbar title above.
229- // RBC renders the "07 Tue" day-column headers via `dayFormat` (week/day time-grid,
230- // TimeGridHeader.js) and the month weekday headers via `weekdayFormat` (Month.js).
231- // These are separate from dayHeaderFormat/monthHeaderFormat (the toolbar title), so we
232- // must set them explicitly or RBC's date-fns defaults ("dd eee") always win.
229+ // RBC renders the "07 Tue" day-column headers via a single, global `dayFormat` key shared
230+ // by Day, Week AND our custom work_week view (all render through TimeGridHeader.js), and
231+ // the month weekday headers via `weekdayFormat` (Month.js). These are separate from
232+ // dayHeaderFormat/monthHeaderFormat (the toolbar title), so we must set them explicitly or
233+ // RBC's date-fns defaults ("dd eee") always win.
233234 if ( monthHeaderPattern ) {
234235 formats . weekdayFormat = ( date : Date , culture : string , loc : DateLocalizer ) =>
235236 loc . format ( date , monthHeaderPattern , culture ) ;
236237 }
237238
238- // RBC exposes a single global `dayFormat` shared by the day AND week column headers, so
239- // when a day item and a week item each carry a different "Header day format" we can only
240- // honor one. Precedence matches `chosenTimeGutter` below (week → day → work_week) for
241- // consistency across the shared-key formats. weekHeaderPattern already folds in
242- // week/work_week; dayHeaderPattern is the "day" item .
243- const columnDayPattern : string | undefined = weekHeaderPattern || dayHeaderPattern ;
244- if ( weekHeaderPattern && dayHeaderPattern && weekHeaderPattern !== dayHeaderPattern ) {
245- console . warn (
246- `[Calendar] Both week and day "Header day format" are set to different patterns ` +
247- `(" ${ weekHeaderPattern } " vs " ${ dayHeaderPattern } "). react-big-calendar shares a single ` +
248- `column-header format, so " ${ columnDayPattern } " will be used for both views.`
249- ) ;
250- }
239+ // Because `dayFormat` is shared, we can't set it once for all views — a pattern meant for
240+ // Week would leak into work_week ( and vice versa). Instead resolve it from whichever view
241+ // is actually on screen right now, and only for the views that render through TimeGridHeader.
242+ // When that view has no custom pattern of its own, leave `dayFormat` unset so RBC's default
243+ // ("dd eee") applies — no more inheriting a sibling view's pattern .
244+ const columnDayPattern : string | undefined =
245+ activeView === "day"
246+ ? dayHeaderPattern
247+ : activeView === "week"
248+ ? weekOwnPattern
249+ : activeView === "work_week"
250+ ? workWeekOwnPattern
251+ : undefined ;
251252 if ( columnDayPattern ) {
252253 formats . dayFormat = ( date : Date , culture : string , loc : DateLocalizer ) =>
253254 loc . format ( date , columnDayPattern , culture ) ;
254255 }
255256
257+ // Toolbar title range for week/work_week — same active-view resolution as the column
258+ // header above, so the title and the columns always agree on which pattern is showing.
259+ const weekRangePattern =
260+ activeView === "week" ? weekOwnPattern : activeView === "work_week" ? workWeekOwnPattern : undefined ;
261+ if ( weekRangePattern ) {
262+ formats . dayRangeHeaderFormat = (
263+ range : { start : Date ; end : Date } ,
264+ culture : string ,
265+ loc : DateLocalizer
266+ ) =>
267+ `${ loc . format ( range . start , weekRangePattern , culture ) } – ${ loc . format ( range . end , weekRangePattern , culture ) } ` ;
268+ }
269+
256270 const agendaHeaderPattern = getPattern ( byType . get ( "agenda" ) ?. customViewHeaderDayFormat ) ;
257271 if ( agendaHeaderPattern ) {
258272 formats . agendaHeaderFormat = ( range : { start : Date ; end : Date } , culture : string , loc : DateLocalizer ) =>
0 commit comments