UI/update sidebar (#480)

* update minicalendar

* update left sidebar

* chore: update twake-mui to version 1.1.4

- Update @linagora/twake-mui from local file to npm package 1.1.4
- Add margin to TempCalendarsInput section in sidebar
- Remove margin from PeopleSearch component (moved to parent)

* Changed wording on my calendars and event creation button

---------

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
lenhanphung
2026-02-02 16:02:23 +07:00
committed by GitHub
parent 0a8051870a
commit 5ae838c425
13 changed files with 116 additions and 88 deletions
+12 -2
View File
@@ -140,7 +140,10 @@ export function PeopleSearch({
...params.InputProps,
startAdornment: (
<>
<PeopleOutlineOutlinedIcon sx={{ mr: 1, color: "action.active" }} />
<PeopleOutlineOutlinedIcon
fontSize="small"
sx={{ mr: 1, color: "action.active" }}
/>
{params.InputProps.startAdornment}
</>
),
@@ -275,7 +278,14 @@ export function PeopleSearch({
);
onChange(event, mapped);
}}
slotProps={customSlotProps}
slotProps={{
...customSlotProps,
popper: {
placement: "bottom-start",
sx: { minWidth: "300px", ...customSlotProps?.popper?.sx },
...customSlotProps?.popper,
},
}}
// When render input is custom, the adornments should be handled by the custom component
forcePopupIcon={!customRenderInput}
disableClearable={!!customRenderInput}
+1 -5
View File
@@ -25,7 +25,7 @@
.sidebar
border-right 2px solid #f3f4f6
width 350px
width 270px
height 100%
flex-direction column
overflow-y: scroll
@@ -86,10 +86,6 @@
gap 30px
font-family "Segoe UI", Tahoma, Geneva, Verdana, sans-serif
/* mini calendar style */
.MuiDayCalendar-weekContainer:has(.selectedWeek)
background-color lightgray !important
/* sidebar header */
.sidebar-calendar h2
font-size 1.3rem
+23 -14
View File
@@ -597,8 +597,11 @@ export default function CalendarApp({
<Box
className="sidebar"
sx={{
padding: "0 15px 16px 25px",
position: "relative",
paddingTop: 0,
paddingBottom: 3,
paddingLeft: 3,
paddingRight: 2,
width: "270px",
}}
>
<Box
@@ -607,11 +610,11 @@ export default function CalendarApp({
top: 0,
zIndex: 10,
backgroundColor: "#fff",
paddingTop: "16px",
paddingTop: 3,
}}
>
<Button
size="large"
size="medium"
variant="contained"
fullWidth
onClick={() =>
@@ -619,9 +622,13 @@ export default function CalendarApp({
}
sx={{
borderRadius: radius.lg,
fontSize: "16px",
fontWeight: 500,
lineHeight: "normal",
}}
>
<AddIcon /> <p>{t("event.createEvent")}</p>
<AddIcon sx={{ marginRight: 0.5, fontSize: "20px" }} />{" "}
{t("event.createEvent")}
</Button>
</Box>
@@ -632,15 +639,17 @@ export default function CalendarApp({
setSelectedMiniDate={setSelectedMiniDate}
dottedEvents={dottedEvents}
/>
<TempCalendarsInput
tempUsers={tempUsers}
setTempUsers={setTempUsers}
handleToggleEventPreview={() => {
eventHandlers.handleDateSelect(null as unknown as DateSelectArg);
}}
selectedCalendars={selectedCalendars}
setSelectedCalendars={setSelectedCalendars}
/>
<Box sx={{ mb: 3, mt: 2 }}>
<TempCalendarsInput
tempUsers={tempUsers}
setTempUsers={setTempUsers}
handleToggleEventPreview={() => {
eventHandlers.handleDateSelect(null as unknown as DateSelectArg);
}}
selectedCalendars={selectedCalendars}
setSelectedCalendars={setSelectedCalendars}
/>
</Box>
<div className="calendarList">
<CalendarSelection
selectedCalendars={selectedCalendars}
+15 -5
View File
@@ -17,7 +17,7 @@ import {
} from "@linagora/twake-mui";
import AddIcon from "@mui/icons-material/Add";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import { useEffect, useMemo, useState } from "react";
import { useI18n } from "twake-i18n";
import CalendarPopover from "./CalendarModal";
@@ -54,7 +54,18 @@ function CalendarAccordion({
<Accordion
defaultExpanded={defaultExpanded}
expanded={expended}
style={{ width: "100%", padding: 0, margin: 0, boxShadow: "none" }}
style={{
width: "100%",
padding: 0,
margin: 0,
marginBottom: "12px",
boxShadow: "none",
}}
sx={{
"&::before": {
display: "none",
},
}}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
@@ -70,7 +81,7 @@ function CalendarAccordion({
},
}}
>
<Typography component="h3">{title}</Typography>
<span>{title}</span>
{showAddButton && (
<IconButton
component="span"
@@ -254,7 +265,6 @@ function CalendarSelector({
alignItems: "center",
justifyContent: "space-between",
transition: "background-color 0.2s ease",
padding: "8px 24px 8px 16px",
"& .MoreBtn": { opacity: 0 },
"&:hover": {
backgroundColor: "#F3F3F6",
@@ -290,7 +300,7 @@ function CalendarSelector({
</span>
</label>
<IconButton className="MoreBtn" onClick={handleClick}>
<MoreVertIcon />
<MoreHorizIcon />
</IconButton>
</ListItem>
<Menu id={id} anchorEl={anchorEl} open={open} onClose={handleClose}>
+11 -1
View File
@@ -10,6 +10,7 @@ import { DateCalendar } from "@mui/x-date-pickers";
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import moment from "moment";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import { useEffect, useState } from "react";
import { useI18n } from "twake-i18n";
@@ -65,7 +66,16 @@ export function MiniCalendar({
);
}}
views={["month", "day"]}
sx={{ width: "100%" }}
slots={{
switchViewIcon: KeyboardArrowDownIcon,
}}
sx={{
width: "100%",
height: "300px",
"& .MuiPickersCalendarHeader-root": {
marginTop: 3,
},
}}
slotProps={{
day: (ownerState) => {
const date = ownerState.day.toDate();
@@ -213,7 +213,6 @@ export default function SearchBar() {
ref={containerRef}
sx={{
margin: "0 auto",
height: "44px",
position: "relative",
width: extended ? searchWidth : "auto",
transition: "width 0.25s ease-out",
+4 -4
View File
@@ -1,9 +1,9 @@
{
"locale": "en-gb",
"calendar": {
"personal": "Personal Calendars",
"delegated": "Delegated Calendars",
"other": "Other Calendars",
"personal": "My calendars",
"delegated": "Delegated calendars",
"other": "Other calendars",
"caldav_access": "CalDAV access",
"secretUrl": "Secret URL",
"secretUrlDesc": "The secret address can be used to view all calendar events even without access permissions. You can reset your current secret address and get a new one.",
@@ -85,7 +85,7 @@
"hex": "Hex"
},
"event": {
"createEvent": "Create Event",
"createEvent": "Create",
"updateEvent": "Update Event",
"organizer": "Organizer",
"untitled": "Untitled",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"locale": "fr-fr",
"calendar": {
"personal": "Calendriers personnels",
"personal": "Mes calendriers",
"delegated": "Calendriers délégués",
"other": "Autres calendriers",
"caldav_access": "Accès CalDAV",
@@ -87,7 +87,7 @@
"hex": "Hex"
},
"event": {
"createEvent": "Créer un événement",
"createEvent": "Créer",
"updateEvent": "Mettre à jour un événement",
"organizer": "Organisateur",
"untitled": "Sans titre",
@@ -248,7 +248,7 @@
"label": "Libre",
"tooltip": "Les autres vous voient comme disponible pendant la plage horaire de cet événement."
},
"attendingQuestion": "Vous participez ?",
"attendingQuestion": "Participer ?",
"ACCEPTED": "Accepter",
"TENTATIVE": "Peut-être",
"DECLINED": "Décliner",
+24
View File
@@ -59,6 +59,30 @@ class IntersectionObserverMock {
(global as any).IntersectionObserver = IntersectionObserverMock;
// Suppress jsdom CSS selector parsing errors for Emotion/MUI
if (typeof window !== "undefined" && window.getComputedStyle) {
const originalGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = function (
element: Element,
pseudoElement?: string | null
) {
try {
return originalGetComputedStyle.call(this, element, pseudoElement);
} catch (error) {
// If CSS selector parsing fails, return a minimal computed style
if (
error instanceof Error &&
error.message.includes("is not a valid selector")
) {
return {
getPropertyValue: () => "",
} as CSSStyleDeclaration;
}
throw error;
}
};
}
beforeAll(() => {
console.warn = (...args: unknown[]) => {
if (