From acce8d1425b1351216a93e38bdcb2a6ff8ea25bc Mon Sep 17 00:00:00 2001 From: Sylvain Zimmer Date: Wed, 11 Feb 2026 23:35:46 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(sharing)=20add=20shared=20calendars,?= =?UTF-8?q?=20remove=20"agenda"=20wording?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/calendar-list/CalendarList.tsx | 51 +++++++++++++++- .../hooks/useCalendarListState.ts | 7 +++ .../calendar/contexts/CalendarContext.tsx | 21 +++++++ .../src/features/i18n/translations.json | 58 +++++++++---------- 4 files changed, 106 insertions(+), 31 deletions(-) diff --git a/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/CalendarList.tsx b/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/CalendarList.tsx index 40f010d..79b049c 100644 --- a/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/CalendarList.tsx +++ b/src/frontend/apps/calendars/src/features/calendar/components/calendar-list/CalendarList.tsx @@ -20,7 +20,8 @@ import { extractCaldavPath } from "./utils"; export const CalendarList = () => { const { t } = useTranslation(); const { - davCalendars, + ownedCalendars, + sharedCalendars, visibleCalendarUrls, toggleCalendarVisibility, createCalendar, @@ -34,6 +35,7 @@ export const CalendarList = () => { deleteState, shareModalState, isMyCalendarsExpanded, + isSharedCalendarsExpanded, openMenuUrl, handleOpenCreateModal, handleOpenEditModal, @@ -47,6 +49,7 @@ export const CalendarList = () => { handleMenuToggle, handleCloseMenu, handleToggleMyCalendars, + handleToggleSharedCalendars, } = useCalendarListState({ createCalendar, updateCalendar, @@ -138,7 +141,7 @@ export const CalendarList = () => { {isMyCalendarsExpanded && (
- {davCalendars.map((calendar) => ( + {ownedCalendars.map((calendar) => ( {
)} + + {sharedCalendars.length > 0 && ( +
+
+ +
+ {isSharedCalendarsExpanded && ( +
+ {sharedCalendars.map((calendar) => ( + + ))} +
+ )} +
+ )} (null); // Modal handlers @@ -159,6 +160,10 @@ export const useCalendarListState = ({ setIsMyCalendarsExpanded((prev) => !prev); }, []); + const handleToggleSharedCalendars = useCallback(() => { + setIsSharedCalendarsExpanded((prev) => !prev); + }, []); + return { // Modal state modalState, @@ -167,6 +172,7 @@ export const useCalendarListState = ({ // Expansion state isMyCalendarsExpanded, + isSharedCalendarsExpanded, openMenuUrl, // Modal handlers @@ -190,5 +196,6 @@ export const useCalendarListState = ({ // Expansion handlers handleToggleMyCalendars, + handleToggleSharedCalendars, }; }; diff --git a/src/frontend/apps/calendars/src/features/calendar/contexts/CalendarContext.tsx b/src/frontend/apps/calendars/src/features/calendar/contexts/CalendarContext.tsx index e889517..99d7587 100644 --- a/src/frontend/apps/calendars/src/features/calendar/contexts/CalendarContext.tsx +++ b/src/frontend/apps/calendars/src/features/calendar/contexts/CalendarContext.tsx @@ -48,6 +48,8 @@ export interface CalendarContextType { caldavService: CalDavService; adapter: EventCalendarAdapter; davCalendars: CalDavCalendar[]; + ownedCalendars: CalDavCalendar[]; + sharedCalendars: CalDavCalendar[]; visibleCalendarUrls: Set; isLoading: boolean; isConnected: boolean; @@ -107,6 +109,23 @@ export const CalendarContextProvider = ({ const [currentDate, setCurrentDate] = useState(new Date()); const [selectedDate, setSelectedDate] = useState(new Date()); + const { ownedCalendars, sharedCalendars } = useMemo(() => { + const homeUrl = caldavService.getAccount()?.homeUrl; + if (!homeUrl) { + return { ownedCalendars: davCalendars, sharedCalendars: [] }; + } + const owned: CalDavCalendar[] = []; + const shared: CalDavCalendar[] = []; + for (const cal of davCalendars) { + if (cal.url.startsWith(homeUrl)) { + owned.push(cal); + } else { + shared.push(cal); + } + } + return { ownedCalendars: owned, sharedCalendars: shared }; + }, [davCalendars, caldavService]); + const refreshCalendars = useCallback(async () => { try { setIsLoading(true); @@ -325,6 +344,8 @@ export const CalendarContextProvider = ({ caldavService, adapter, davCalendars, + ownedCalendars, + sharedCalendars, visibleCalendarUrls, isLoading, isConnected, diff --git a/src/frontend/apps/calendars/src/features/i18n/translations.json b/src/frontend/apps/calendars/src/features/i18n/translations.json index d0b8d8e..1d1a9a1 100644 --- a/src/frontend/apps/calendars/src/features/i18n/translations.json +++ b/src/frontend/apps/calendars/src/features/i18n/translations.json @@ -804,8 +804,8 @@ } }, "list": { - "myCalendars": "Mes agendas", - "sharedCalendars": "Agendas partagés", + "myCalendars": "Mes calendriers", + "sharedCalendars": "Calendriers partagés", "shared": "(partagé)", "showCalendar": "Afficher le calendrier", "edit": "Modifier", @@ -906,32 +906,32 @@ } }, "createCalendar": { - "title": "Créer un agenda", + "title": "Créer un calendrier", "name": "Nom", - "namePlaceholder": "Nom de l'agenda", + "namePlaceholder": "Nom du calendrier", "nameRequired": "Le nom est requis", "color": "Couleur", "description": "Description", - "descriptionPlaceholder": "Description de l'agenda (optionnel)", + "descriptionPlaceholder": "Description du calendrier (optionnel)", "cancel": "Annuler", "create": "Créer" }, "editCalendar": { - "title": "Modifier l'agenda", + "title": "Modifier le calendrier", "save": "Enregistrer" }, "deleteCalendar": { - "title": "Supprimer l'agenda", - "message": "Êtes-vous sûr de vouloir supprimer l'agenda \"{{name}}\" ? Cette action est irréversible.", + "title": "Supprimer le calendrier", + "message": "Êtes-vous sûr de vouloir supprimer le calendrier \"{{name}}\" ? Cette action est irréversible.", "confirm": "Supprimer" }, "shareCalendar": { - "title": "Partager l'agenda", + "title": "Partager le calendrier", "emailPlaceholder": "Entrez l'adresse email", "share": "Partager", "hint": "La personne aura les mêmes droits que vous (lecture et écriture).", - "success": "Agenda partagé avec {{email}}", - "error": "Échec du partage de l'agenda", + "success": "Calendrier partagé avec {{email}}", + "error": "Échec du partage du calendrier", "invalidEmail": "Veuillez entrer une adresse email valide" }, "attendees": { @@ -1109,7 +1109,7 @@ "event": { "createTitle": "Evenement aanmaken", "editTitle": "Evenement bewerken", - "calendar": "Agenda", + "calendar": "Kalender", "title": "Titel", "titlePlaceholder": "Evenement titel", "location": "Locatie", @@ -1178,10 +1178,10 @@ } }, "list": { - "myCalendars": "Mijn agenda's", - "sharedCalendars": "Gedeelde agenda's", + "myCalendars": "Mijn kalenders", + "sharedCalendars": "Gedeelde kalenders", "shared": "(gedeeld)", - "showCalendar": "Agenda tonen", + "showCalendar": "Kalender tonen", "edit": "Bewerken", "delete": "Verwijderen", "share": "Delen", @@ -1202,21 +1202,21 @@ "errorDetails": "Foutdetails" }, "subscription": { - "title": "Agenda-abonnements-URL", - "description": "Gebruik deze URL om u te abonneren op \"{{name}}\" vanuit externe agendatoepassingen (Apple Calendar, Google Calendar, Outlook, etc.).", + "title": "Kalender-abonnements-URL", + "description": "Gebruik deze URL om u te abonneren op \"{{name}}\" vanuit externe kalendertoepassingen (Apple Calendar, Google Calendar, Outlook, etc.).", "loading": "Abonnements-URL wordt gegenereerd...", "copy": "Kopiëren", "copied": "Gekopieerd!", "close": "Sluiten", - "warning": "Deze URL bevat een privétoken. Iedereen met deze link kan uw agenda-evenementen bekijken.", + "warning": "Deze URL bevat een privétoken. Iedereen met deze link kan uw kalender-evenementen bekijken.", "regenerate": "URL regenereren", "regenerateConfirm": { "title": "Abonnements-URL regenereren?", - "message": "Dit maakt de huidige URL ongeldig. Externe agenda's die de oude URL gebruiken zullen niet meer synchroniseren.", + "message": "Dit maakt de huidige URL ongeldig. Externe kalenders die de oude URL gebruiken zullen niet meer synchroniseren.", "confirm": "Regenereren" }, "error": "Genereren van abonnements-URL mislukt. Probeer het opnieuw.", - "errorPermission": "U heeft geen toegang tot deze agenda.", + "errorPermission": "U heeft geen toegang tot deze kalender.", "errorNetwork": "Netwerkfout. Controleer uw verbinding en probeer het opnieuw.", "errorServer": "Serverfout. Probeer het later opnieuw." }, @@ -1280,32 +1280,32 @@ } }, "createCalendar": { - "title": "Agenda aanmaken", + "title": "Kalender aanmaken", "name": "Naam", - "namePlaceholder": "Agenda naam", + "namePlaceholder": "Kalender naam", "nameRequired": "Naam is verplicht", "color": "Kleur", "description": "Beschrijving", - "descriptionPlaceholder": "Agenda beschrijving (optioneel)", + "descriptionPlaceholder": "Kalender beschrijving (optioneel)", "cancel": "Annuleren", "create": "Aanmaken" }, "editCalendar": { - "title": "Agenda bewerken", + "title": "Kalender bewerken", "save": "Opslaan" }, "deleteCalendar": { - "title": "Agenda verwijderen", - "message": "Weet u zeker dat u de agenda \"{{name}}\" wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.", + "title": "Kalender verwijderen", + "message": "Weet u zeker dat u de kalender \"{{name}}\" wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.", "confirm": "Verwijderen" }, "shareCalendar": { - "title": "Agenda delen", + "title": "Kalender delen", "emailPlaceholder": "Voer e-mailadres in", "share": "Delen", "hint": "De persoon krijgt dezelfde rechten als u (lezen en schrijven).", - "success": "Agenda gedeeld met {{email}}", - "error": "Delen van agenda mislukt", + "success": "Kalender gedeeld met {{email}}", + "error": "Delen van kalender mislukt", "invalidEmail": "Voer een geldig e-mailadres in" }, "attendees": {