calendar list display improvments (#115)

* [#60] added collapsible groups

* [#60] factorized code and fixed tests

* fixup! [#60] added collapsible groups

* fixup! [#60] added collapsible groups

---------

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-09-18 18:01:08 +02:00
committed by GitHub
parent b8cef20b9e
commit 8a7d2f742a
3 changed files with 136 additions and 61 deletions
+112 -58
View File
@@ -1,12 +1,78 @@
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import Accordion from "@mui/material/Accordion";
import AccordionDetails from "@mui/material/AccordionDetails";
import AccordionSummary from "@mui/material/AccordionSummary";
import Typography from "@mui/material/Typography";
import { useAppSelector } from "../../app/hooks";
import AddIcon from "@mui/icons-material/Add";
import { useEffect, useState } from "react";
import { useState } from "react";
import CalendarPopover from "../../features/Calendars/CalendarModal";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import IconButton from "@mui/material/IconButton";
import Checkbox from "@mui/material/Checkbox";
import Button from "@mui/material/Button";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
function CalendarAccordion({
title,
calendars,
selectedCalendars,
handleToggle,
showAddButton = false,
onAddClick,
defaultExpanded = false,
setOpen,
}: {
title: string;
calendars: string[];
selectedCalendars: string[];
handleToggle: (id: string) => void;
showAddButton?: boolean;
onAddClick?: Function;
defaultExpanded?: boolean;
setOpen: Function;
}) {
const allCalendars = useAppSelector((state) => state.calendars.list);
if (calendars.length === 0) return null;
const [expended, setExpended] = useState(defaultExpanded);
return (
<Accordion defaultExpanded={defaultExpanded} expanded={expended}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`${title}-content`}
id={`${title}-header`}
className="calendarListHeader"
onClick={() => setExpended(!expended)}
>
<Typography component="h3">{title}</Typography>
{showAddButton && (
<IconButton
component="span"
onClick={(e) => {
expended && e.stopPropagation();
onAddClick && onAddClick();
}}
>
<AddIcon />
</IconButton>
)}
</AccordionSummary>
<AccordionDetails>
{calendars.map((id) =>
CalendarSelector(
allCalendars,
id,
selectedCalendars,
handleToggle,
() => setOpen(id)
)
)}
</AccordionDetails>
</Accordion>
);
}
export default function CalendarSelection({
selectedCalendars,
@@ -17,6 +83,7 @@ export default function CalendarSelection({
}) {
const userId = useAppSelector((state) => state.user.userData.openpaasId);
const calendars = useAppSelector((state) => state.calendars.list);
const personnalCalendars = Object.keys(calendars).filter(
(id) => id.split("/")[0] === userId
);
@@ -26,6 +93,7 @@ export default function CalendarSelection({
const sharedCalendars = Object.keys(calendars).filter(
(id) => id.split("/")[0] !== userId && !calendars[id].delegated
);
const handleCalendarToggle = (name: string) => {
setSelectedCalendars((prev: string[]) =>
prev.includes(name) ? prev.filter((n) => n !== name) : [...prev, name]
@@ -37,67 +105,53 @@ export default function CalendarSelection({
return (
<>
<div>
<div className="calendarListHeader">
<h3>Personnal Calendars</h3>
<Button onClick={() => setAnchorElCal(document.body)}>
<AddIcon />
</Button>
</div>
{personnalCalendars.map((id) =>
CalendarSelector(
calendars,
id,
selectedCalendars,
handleCalendarToggle,
() => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}
)
)}
{delegatedCalendars.length > 0 && (
<>
<span className="calendarListHeader">
<h3>Delegated Calendars</h3>
</span>
{delegatedCalendars.map((id) =>
CalendarSelector(
calendars,
id,
selectedCalendars,
handleCalendarToggle,
() => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}
)
)}
</>
)}
{sharedCalendars.length > 0 && (
<>
<span className="calendarListHeader">
<h3>Shared Calendars</h3>
</span>
{sharedCalendars.map((id) =>
CalendarSelector(
calendars,
id,
selectedCalendars,
handleCalendarToggle,
() => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}
)
)}
</>
)}
<CalendarAccordion
title="Personnal Calendars"
calendars={personnalCalendars}
selectedCalendars={selectedCalendars}
handleToggle={handleCalendarToggle}
showAddButton
onAddClick={() => setAnchorElCal(document.body)}
setOpen={(id: string) => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}}
defaultExpanded
/>
<CalendarAccordion
title="Delegated Calendars"
calendars={delegatedCalendars}
selectedCalendars={selectedCalendars}
handleToggle={handleCalendarToggle}
defaultExpanded
setOpen={(id: string) => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}}
/>
<CalendarAccordion
title="Other Calendars"
calendars={sharedCalendars}
selectedCalendars={selectedCalendars}
showAddButton
onAddClick={() => {
setAnchorElCal(document.body);
}}
handleToggle={handleCalendarToggle}
setOpen={(id: string) => {
setAnchorElCal(document.body);
setSelectedCalId(id);
}}
/>
</div>
<CalendarPopover
anchorEl={anchorElCal}
open={Boolean(anchorElCal)}
onClose={() => {
setSelectedCalId("");
setAnchorElCal(null);
}}
calendar={calendars[selectedCalId] ?? undefined}