diff --git a/packages/pluggableWidgets/calendar-web/src/Calendar.editorConfig.ts b/packages/pluggableWidgets/calendar-web/src/Calendar.editorConfig.ts
index 0cd2731f37..229dc2961f 100644
--- a/packages/pluggableWidgets/calendar-web/src/Calendar.editorConfig.ts
+++ b/packages/pluggableWidgets/calendar-web/src/Calendar.editorConfig.ts
@@ -32,6 +32,23 @@ export function getProperties(values: CalendarPreviewProps, defaultProperties: P
hidePropertiesIn(defaultProperties, values, ["maxHeight", "overflowY"]);
}
+ // Hide custom week range properties when the view is set to 'standard'
+ if (values.view === "standard") {
+ hidePropertiesIn(defaultProperties, values, [
+ "defaultViewCustom",
+ "showSunday",
+ "showMonday",
+ "showTuesday",
+ "showWednesday",
+ "showThursday",
+ "showFriday",
+ "showSaturday",
+ "customViewCaption"
+ ]);
+ } else {
+ hidePropertyIn(defaultProperties, values, "defaultViewStandard");
+ }
+
// Show/hide title properties based on selection
if (values.titleType === "attribute") {
hidePropertyIn(defaultProperties, values, "titleExpression");
diff --git a/packages/pluggableWidgets/calendar-web/src/Calendar.editorPreview.tsx b/packages/pluggableWidgets/calendar-web/src/Calendar.editorPreview.tsx
index 06cf94cf31..f80ee07afe 100644
--- a/packages/pluggableWidgets/calendar-web/src/Calendar.editorPreview.tsx
+++ b/packages/pluggableWidgets/calendar-web/src/Calendar.editorPreview.tsx
@@ -1,7 +1,7 @@
import classnames from "classnames";
import * as dateFns from "date-fns";
import { ReactElement, createElement } from "react";
-import { Calendar, dateFnsLocalizer } from "react-big-calendar";
+import { Calendar, dateFnsLocalizer, EventPropGetter } from "react-big-calendar";
import { CalendarPreviewProps } from "../typings/CalendarProps";
import { CustomToolbar } from "./components/Toolbar";
import { constructWrapperStyle, WrapperStyleProps } from "./utils/style-utils";
@@ -73,15 +73,19 @@ export function preview(props: CalendarPreviewProps): ReactElement {
const { class: className } = props;
const wrapperStyle = constructWrapperStyle(props as WrapperStyleProps);
+ // Cast eventPropGetter to satisfy preview Calendar generic
+ const previewEventPropGetter = eventPropGetter as unknown as EventPropGetter<(typeof events)[0]>;
+
return (
);
diff --git a/packages/pluggableWidgets/calendar-web/src/Calendar.tsx b/packages/pluggableWidgets/calendar-web/src/Calendar.tsx
index 3983e9d64e..03f60bc04d 100644
--- a/packages/pluggableWidgets/calendar-web/src/Calendar.tsx
+++ b/packages/pluggableWidgets/calendar-web/src/Calendar.tsx
@@ -1,14 +1,15 @@
import classnames from "classnames";
import { ReactElement, createElement } from "react";
-import { DnDCalendar, extractCalendarProps } from "./utils/calendar-utils";
import { CalendarContainerProps } from "../typings/CalendarProps";
+import { CalendarPropsBuilder } from "./helpers/CalendarPropsBuilder";
+import { DnDCalendar } from "./utils/calendar-utils";
import { constructWrapperStyle } from "./utils/style-utils";
import "./ui/Calendar.scss";
export default function MxCalendar(props: CalendarContainerProps): ReactElement {
const { class: className } = props;
const wrapperStyle = constructWrapperStyle(props);
- const calendarProps = extractCalendarProps(props);
+ const calendarProps = new CalendarPropsBuilder(props).build();
return (
diff --git a/packages/pluggableWidgets/calendar-web/src/Calendar.xml b/packages/pluggableWidgets/calendar-web/src/Calendar.xml
index fc7da33603..8759359961 100644
--- a/packages/pluggableWidgets/calendar-web/src/Calendar.xml
+++ b/packages/pluggableWidgets/calendar-web/src/Calendar.xml
@@ -55,7 +55,7 @@
Color attribute
- Attribute containing a valid html color eg: red #FF0000 rgb(250,10,20) rgba(10,10,10, 0.5)
+ Attribute containing a valid HTML color eg: red #FF0000 rgb(250,10,20) rgba(10,10,10, 0.5)
@@ -87,15 +87,24 @@
Show event date range
Show the start and end date of the event
-
+
Initial selected view
- Work week and agenda are only available in custom views
+ The default view showed when the calendar is loaded
+
+ Day
+ Week
+ Month
+ Custom
+ Agenda
+
+
+
+ Initial selected view
+ The default view showed when the calendar is loaded
Day
Week
Month
- (Work week)
- (Agenda)
@@ -105,6 +114,52 @@
+
+ Day start hour
+ The hour at which the day view starts (0–23)
+
+
+ Day end hour
+ The hour at which the day view ends (1–24)
+
+
+
+ Custom view caption
+ Label used for the custom work-week button and title. Defaults to "Custom".
+
+ Custom
+
+
+
+
+
+ Monday
+ Show Monday in the custom work-week view
+
+
+ Tuesday
+ Show Tuesday in the custom work-week view
+
+
+ Wednesday
+ Show Wednesday in the custom work-week view
+
+
+ Thursday
+ Show Thursday in the custom work-week view
+
+
+ Friday
+ Show Friday in the custom work-week view
+
+
+ Sunday
+ Show Sunday in the custom work-week view
+
+
+ Saturday
+ Show Saturday in the custom work-week view
+
@@ -115,7 +170,7 @@
-
+
On click action
@@ -134,7 +189,7 @@
-
+
On change action
The change event is triggered on moving/dragging an item or changing the start or end time of by resizing an item
@@ -218,6 +273,10 @@
Hidden
+
+ Show all events
+ Auto-adjust calendar height to display all events without "more" links
+
diff --git a/packages/pluggableWidgets/calendar-web/src/__tests__/Calendar.spec.tsx b/packages/pluggableWidgets/calendar-web/src/__tests__/Calendar.spec.tsx
index f656c5e60a..1229a8d7cc 100644
--- a/packages/pluggableWidgets/calendar-web/src/__tests__/Calendar.spec.tsx
+++ b/packages/pluggableWidgets/calendar-web/src/__tests__/Calendar.spec.tsx
@@ -4,26 +4,42 @@ import { ListValueBuilder } from "@mendix/widget-plugin-test-utils";
import Calendar from "../Calendar";
import { CalendarContainerProps } from "../../typings/CalendarProps";
-const defaultProps: CalendarContainerProps = {
+const customViewProps: CalendarContainerProps = {
name: "calendar-test",
class: "calendar-class",
tabIndex: 0,
databaseDataSource: new ListValueBuilder().withItems([]).build(),
titleType: "attribute",
- view: "standard",
- defaultView: "month",
+ view: "custom",
+ defaultViewStandard: "month",
+ defaultViewCustom: "work_week",
editable: "default",
enableCreate: true,
widthUnit: "percentage",
width: 100,
heightUnit: "pixels",
height: 400,
+ minHour: 0,
+ maxHour: 24,
minHeightUnit: "pixels",
minHeight: 400,
maxHeightUnit: "none",
maxHeight: 400,
overflowY: "auto",
- showEventDate: true
+ showEventDate: true,
+ showSunday: false,
+ showMonday: true,
+ showTuesday: true,
+ showWednesday: true,
+ showThursday: true,
+ showFriday: true,
+ showSaturday: false,
+ showAllEvents: true
+};
+
+const standardViewProps: CalendarContainerProps = {
+ ...customViewProps,
+ view: "standard"
};
beforeAll(() => {
@@ -37,13 +53,18 @@ afterAll(() => {
describe("Calendar", () => {
it("renders correctly with basic props", () => {
- const calendar = render( );
+ const calendar = render( );
expect(calendar).toMatchSnapshot();
});
it("renders with correct class name", () => {
- const { container } = render( );
+ const { container } = render( );
expect(container.querySelector(".widget-calendar")).toBeTruthy();
expect(container.querySelector(".calendar-class")).toBeTruthy();
});
+
+ it("does not render custom view button in standard view", () => {
+ const { queryByText } = render( );
+ expect(queryByText("Custom")).toBeNull();
+ });
});
diff --git a/packages/pluggableWidgets/calendar-web/src/__tests__/__snapshots__/Calendar.spec.tsx.snap b/packages/pluggableWidgets/calendar-web/src/__tests__/__snapshots__/Calendar.spec.tsx.snap
index 9120b741de..d661e1424a 100644
--- a/packages/pluggableWidgets/calendar-web/src/__tests__/__snapshots__/Calendar.spec.tsx.snap
+++ b/packages/pluggableWidgets/calendar-web/src/__tests__/__snapshots__/Calendar.spec.tsx.snap
@@ -49,7 +49,7 @@ exports[`Calendar renders correctly with basic props 1`] = `
- April 2025
+ Apr 28 – May 02
Month
+
+ Custom
+
+
+ Agenda
+
-
+ class="rbc-label rbc-time-header-gutter"
+ />
- 30
+
+ 28 Mon
+
- 31
+
+ 29 Tue
+
- 01
+
+ 30 Wed
+
- 02
+
+ 01 Thu
+
- 03
+
+ 02 Fri
+
+
+
-
- 04
-
+ class="rbc-row-bg"
+ >
+
+
+
+
+
-
-
-
-
-
-
-
+ class="rbc-timeslot-group"
+ >
+
+
+ 7:00 AM
+
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+ 8:00 AM
+
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+ 9:00 AM
+
+
+
+
-
-
+ class="rbc-timeslot-group"
+ >
+
+
+ 10:00 AM
+
+
+
+
+
+
-
- 14
-
+ 12:00 PM
+
+
+
+
+
+
+
-
-
-
-
-
-
-
- 20
-
+ 6:00 PM
+
-
- 21
-
-
+ class="rbc-time-slot"
+ />
+
+
+
+
+
+
-
- 25
-
+ 10:00 PM
+
+
+
+
-
- 26
-
+ 11:00 PM
+
+
-
-
-
+ class="rbc-timeslot-group"
+ >
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+
+ class="rbc-timeslot-group"
+ >
+
+
+
-
-
+ class="rbc-timeslot-group"
+ >
+
+
+
-
- 27
-
-
+ class="rbc-time-slot"
+ />
-
- 28
-
-
+ class="rbc-time-slot"
+ />
+
+
-
- 29
-
-
+ class="rbc-time-slot"
+ />
-
- 30
-
-
+ class="rbc-time-slot"
+ />
+
+
-
- 01
-
-
+ class="rbc-time-slot"
+ />
-
- 02
-
-
+ class="rbc-time-slot"
+ />
+
+
-
- 03
-
-
+ class="rbc-time-slot"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-