diff --git a/__test__/features/Events/EventDisplay.test.tsx b/__test__/features/Events/EventDisplay.test.tsx
index 4e7ea8f..5127fec 100644
--- a/__test__/features/Events/EventDisplay.test.tsx
+++ b/__test__/features/Events/EventDisplay.test.tsx
@@ -82,6 +82,13 @@ describe("Event Preview Display", () => {
end: day.toISOString(),
organizer: { cn: "test", cal_address: "test@test.com" },
},
+ event3: {
+ uid: "event3",
+ calId: "667037022b752d0026472254/cal1",
+ start: day.toISOString(),
+ end: day.toISOString(),
+ organizer: { cn: "test", cal_address: "test@test.com" },
+ },
},
ownerEmails: ["test@test.com"],
},
@@ -797,7 +804,21 @@ describe("Event Preview Display", () => {
}).not.toThrow();
});
});
+ it("renders correctly event data event with empty title", () => {
+ renderWithProviders(
+ ,
+ preloadedState
+ );
+ expect(screen.getByText("event.untitled")).toBeInTheDocument();
+
+ expect(screen.getByText("Calendar")).toBeInTheDocument();
+ });
describe("BUGFIX", () => {
it("doesnt render anything next to date of all day preview", () => {
const allDayState = {
diff --git a/__test__/features/Events/EventModal.test.tsx b/__test__/features/Events/EventModal.test.tsx
index 1fa1822..57d518e 100644
--- a/__test__/features/Events/EventModal.test.tsx
+++ b/__test__/features/Events/EventModal.test.tsx
@@ -1,11 +1,9 @@
import { DateSelectArg } from "@fullcalendar/core";
import { act, fireEvent, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
-import preview from "jest-preview";
import * as eventThunks from "../../../src/features/Calendars/CalendarSlice";
import EventPopover from "../../../src/features/Events/EventModal";
import { api } from "../../../src/utils/apiUtils";
-import { formatDateToYYYYMMDDTHHMMSS } from "../../../src/utils/dateUtils";
import { renderWithProviders } from "../../utils/Renderwithproviders";
jest.mock("../../../src/utils/apiUtils");
diff --git a/src/components/Calendar/utils/calendarUtils.ts b/src/components/Calendar/utils/calendarUtils.ts
index e0d1ddc..2147daf 100644
--- a/src/components/Calendar/utils/calendarUtils.ts
+++ b/src/components/Calendar/utils/calendarUtils.ts
@@ -6,6 +6,7 @@ import { SlotLabelContentArg } from "@fullcalendar/core";
import moment from "moment-timezone";
import { refreshSingularCalendar } from "../../Event/utils/eventUtils";
import { ThunkDispatch } from "@reduxjs/toolkit";
+import { useI18n } from "cozy-ui/transpiled/react/providers/I18n";
export const updateSlotLabelVisibility = (
currentTime: Date,
@@ -58,13 +59,24 @@ export const eventToFullCalendarFormat = (
filteredTempEvents: CalendarEvent[],
userId: string | undefined
) => {
+ const { t } = useI18n();
return filteredEvents
.concat(filteredTempEvents.map((e) => ({ ...e, temp: true })))
.map((e) => {
if (e.calId.split("/")[0] === userId) {
- return { ...e, colors: e.color, editable: true };
+ return {
+ ...e,
+ title: e.title ? e.title : t("event.untitled"),
+ colors: e.color,
+ editable: true,
+ };
}
- return { ...e, colors: e.color, editable: false };
+ return {
+ ...e,
+ title: e.title ? e.title : t("event.untitled"),
+ colors: e.color,
+ editable: false,
+ };
});
};
diff --git a/src/components/Event/EventFormFields.tsx b/src/components/Event/EventFormFields.tsx
index 814703a..4d561d7 100644
--- a/src/components/Event/EventFormFields.tsx
+++ b/src/components/Event/EventFormFields.tsx
@@ -323,7 +323,6 @@ export default function EventFormFields({
// Validation logic
const validateForm = React.useCallback(() => {
return validateEventForm({
- title,
startDate,
startTime,
endDate,
@@ -410,14 +409,7 @@ export default function EventFormFields({
return (
<>
-
- {t("event.form.title")} *
- >
- }
- isExpanded={showMore}
- >
+
{
setTitle(e.target.value);
}}
- error={!!validation.errors.title}
- helperText={validation.errors.title}
size="small"
margin="dense"
inputRef={titleInputRef}
diff --git a/src/components/Event/utils/formValidation.ts b/src/components/Event/utils/formValidation.ts
index 45db7b6..1f3f9cf 100644
--- a/src/components/Event/utils/formValidation.ts
+++ b/src/components/Event/utils/formValidation.ts
@@ -4,7 +4,6 @@ import { combineDateTime } from "./dateTimeHelpers";
* Validation parameters for event form
*/
export interface ValidationParams {
- title: string;
startDate: string;
startTime: string;
endDate: string;
@@ -21,7 +20,6 @@ export interface ValidationParams {
export interface ValidationResult {
isValid: boolean;
errors: {
- title: string;
dateTime: string;
};
}
@@ -33,7 +31,6 @@ export interface ValidationResult {
*/
export function validateEventForm(params: ValidationParams): ValidationResult {
const {
- title,
startDate,
startTime,
endDate,
@@ -44,9 +41,6 @@ export function validateEventForm(params: ValidationParams): ValidationResult {
showMore = false,
} = params;
- const isTitleValid = title.trim().length > 0;
- const shouldShowTitleError = showValidationErrors && !isTitleValid;
-
let isDateTimeValid = true;
let dateTimeError = "";
@@ -154,12 +148,11 @@ export function validateEventForm(params: ValidationParams): ValidationResult {
}
}
- const isValid = isTitleValid && isDateTimeValid;
+ const isValid = isDateTimeValid;
return {
isValid,
errors: {
- title: shouldShowTitleError ? "Title is required" : "",
dateTime: showValidationErrors ? dateTimeError : "",
},
};
diff --git a/src/components/Menubar/Menubar.tsx b/src/components/Menubar/Menubar.tsx
index 8708451..5c87feb 100644
--- a/src/components/Menubar/Menubar.tsx
+++ b/src/components/Menubar/Menubar.tsx
@@ -254,6 +254,7 @@ export function Menubar({
value={lang}
onChange={(e) => {
dispatch(setLanguage(e.target.value));
+ handleLangClose();
}}
variant="outlined"
aria-label={t("menubar.languageSelector")}
diff --git a/src/features/Events/EventDisplayPreview.tsx b/src/features/Events/EventDisplayPreview.tsx
index b9d77de..1091738 100644
--- a/src/features/Events/EventDisplayPreview.tsx
+++ b/src/features/Events/EventDisplayPreview.tsx
@@ -141,175 +141,169 @@ export default function EventPreviewModal({
actionsJustifyContent="center"
style={{ overflow: "auto" }}
title={
- event.title && (
- <>
-
-
- {(window as any).DEBUG && (
- {
- const icsContent = await dlEvent(event);
- const blob = new Blob([icsContent], {
- type: "text/calendar",
- });
- const url = URL.createObjectURL(blob);
+ <>
+
+
+ {(window as any).DEBUG && (
+ {
+ const icsContent = await dlEvent(event);
+ const blob = new Blob([icsContent], {
+ type: "text/calendar",
+ });
+ const url = URL.createObjectURL(blob);
- const link = document.createElement("a");
- link.href = url;
- link.download = `${eventId}.ics`;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- URL.revokeObjectURL(url);
- }}
- >
-
-
- )}
- {user.userData.email === event.organizer?.cal_address &&
- calendar.ownerEmails?.includes(user.userData.email) && (
- {
- if (isRecurring) {
- setAfterChoiceFunc(() => () => {
- setHidePreview(true);
- setOpenUpdateModal(true);
- });
- setOpenEditModePopup("edit");
- } else {
- setHidePreview(true);
- setOpenUpdateModal(true);
- }
- }}
- >
-
-
- )}
- {((event.class !== "PRIVATE" && !isOwn) || isOwn) && (
+ const link = document.createElement("a");
+ link.href = url;
+ link.download = `${eventId}.ics`;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ URL.revokeObjectURL(url);
+ }}
+ >
+
+
+ )}
+ {user.userData.email === event.organizer?.cal_address &&
+ calendar.ownerEmails?.includes(user.userData.email) && (
setToggleActionMenu(e.currentTarget)}
+ onClick={() => {
+ if (isRecurring) {
+ setAfterChoiceFunc(() => () => {
+ setHidePreview(true);
+ setOpenUpdateModal(true);
+ });
+ setOpenEditModePopup("edit");
+ } else {
+ setHidePreview(true);
+ setOpenUpdateModal(true);
+ }
+ }}
>
-
+
)}
-
+ {((event.class !== "PRIVATE" && !isOwn) || isOwn) && (
onClose({}, "backdropClick")}
+ onClick={(e) => setToggleActionMenu(e.currentTarget)}
>
-
+
-
-
-
- {event.class === "PRIVATE" &&
- (isOwn ? (
-
-
-
- ) : (
-
- ))}
- setToggleActionMenu(null)}
+ anchorEl={toggleActionMenu}
>
- {event.title}
-
- {event.transp === "TRANSPARENT" && (
+ {mailSpaUrl && attendees.length > 0 && (
+
+ )}
+ setToggleActionMenu(null)}
+ onOpenDuplicate={() => {
+ setToggleActionMenu(null);
+ setHidePreview(true);
+ setOpenDuplicateModal(true);
+ }}
+ />
+ {user.userData.email === event.organizer?.cal_address && (
+
+ )}
+
+ onClose({}, "backdropClick")}
+ >
+
+
+
+
+
+ {event.class === "PRIVATE" &&
+ (isOwn ? (
- }
- label={t("eventPreview.free.label")}
- />
+
- )}
-
-
- {formatDate(event.start, t, event.allday)}
- {event.end &&
- formatEnd(event.start, event.end, t, event.allday) &&
- ` – ${formatEnd(event.start, event.end, t, event.allday)} ${!event.allday ? getTimezoneOffset(timezone) : ""}`}
+ ) : (
+
+ ))}
+
+ {event.title ? event.title : t("event.untitled")}
- >
- )
+ {event.transp === "TRANSPARENT" && (
+
+ }
+ label={t("eventPreview.free.label")}
+ />
+
+ )}
+
+
+ {formatDate(event.start, t, event.allday)}
+ {event.end &&
+ formatEnd(event.start, event.end, t, event.allday) &&
+ ` – ${formatEnd(event.start, event.end, t, event.allday)} ${!event.allday ? getTimezoneOffset(timezone) : ""}`}
+
+ >
}
actions={
currentUserAttendee &&
diff --git a/src/features/Events/EventModal.tsx b/src/features/Events/EventModal.tsx
index 91f441e..0eaf6f1 100644
--- a/src/features/Events/EventModal.tsx
+++ b/src/features/Events/EventModal.tsx
@@ -33,7 +33,6 @@ import { addDays } from "../../components/Event/utils/dateRules";
import { useI18n } from "cozy-ui/transpiled/react/providers/I18n";
function EventPopover({
- anchorEl,
open,
onClose,
selectedRange,
@@ -50,6 +49,7 @@ function EventPopover({
event?: CalendarEvent;
}) {
const dispatch = useAppDispatch();
+ const { t, lang } = useI18n();
const organizer = useAppSelector((state) => state.user.organiserData);
const userId =
@@ -673,8 +673,6 @@ function EventPopover({
await updateTempCalendar(tempList, newEvent, dispatch, calendarRange);
}
};
- const { t } = useI18n();
-
const dialogActions = (
{!showMore && (
diff --git a/src/locales/en.json b/src/locales/en.json
index 6423faa..740c4c5 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -65,6 +65,7 @@
"createEvent": "Create Event",
"updateEvent": "Update Event",
"organizer": "Organizer",
+ "untitled": "Untitled",
"repeat": {
"repeatEvery": "Repeat every",
"frequency": {
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 1770bad..9cca5c5 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -65,6 +65,7 @@
"createEvent": "Créer un événement",
"updateEvent": "Mettre à jour un événement",
"organizer": "Organisateur",
+ "untitled": "Sans titre",
"repeat": {
"repeatEvery": "Répéter tous les",
"frequency": {