Fix button style, button type (#450)
This commit is contained in:
@@ -90,6 +90,7 @@ export function AccessTab({ calendar }: { calendar: Calendar }) {
|
||||
fullWidth
|
||||
label={t("calendar.caldav_access")}
|
||||
value={calDAVLink}
|
||||
size="small"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
@@ -110,6 +111,7 @@ export function AccessTab({ calendar }: { calendar: Calendar }) {
|
||||
fullWidth
|
||||
label={t("calendar.secretUrl")}
|
||||
value={secretLink}
|
||||
size="small"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
@@ -120,7 +122,12 @@ export function AccessTab({ calendar }: { calendar: Calendar }) {
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button variant="contained" onClick={handleResetSecretLink}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
onClick={handleResetSecretLink}
|
||||
sx={{ borderRadius: "4px" }}
|
||||
>
|
||||
{t("actions.reset")}
|
||||
</Button>
|
||||
</Box>
|
||||
@@ -142,9 +149,11 @@ export function AccessTab({ calendar }: { calendar: Calendar }) {
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
onClick={handleExport}
|
||||
startIcon={!exportLoading && <FileDownloadOutlinedIcon />}
|
||||
disabled={exportLoading}
|
||||
sx={{ borderRadius: "4px" }}
|
||||
>
|
||||
{exportLoading ? (
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
|
||||
@@ -56,15 +56,22 @@ export function ImportTab({
|
||||
<Box mt={2}>
|
||||
{importMode === "file" && (
|
||||
<>
|
||||
<Button variant="outlined" component="label" sx={{ mb: 1 }}>
|
||||
{t("common.select_file")}
|
||||
<input
|
||||
type="file"
|
||||
hidden
|
||||
accept=".ics"
|
||||
onChange={(e) => setImportFile(e.target.files?.[0] ?? null)}
|
||||
/>
|
||||
</Button>
|
||||
<Box mb={1}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
component="label"
|
||||
size="medium"
|
||||
sx={{ borderRadius: "12px" }}
|
||||
>
|
||||
{t("common.select_file")}
|
||||
<input
|
||||
type="file"
|
||||
hidden
|
||||
accept=".ics"
|
||||
onChange={(e) => setImportFile(e.target.files?.[0] ?? null)}
|
||||
/>
|
||||
</Button>
|
||||
</Box>
|
||||
{importFile && (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{importFile.name}
|
||||
|
||||
@@ -67,6 +67,8 @@ export function SettingsTab({
|
||||
showMore={false}
|
||||
description={description}
|
||||
setDescription={setDescription}
|
||||
buttonVariant="contained"
|
||||
buttonColor="secondary"
|
||||
/>
|
||||
|
||||
<Box mt={2}>
|
||||
@@ -88,7 +90,8 @@ export function SettingsTab({
|
||||
value={visibility}
|
||||
exclusive
|
||||
onChange={(e, val) => val && setVisibility(val)}
|
||||
size="small"
|
||||
size="medium"
|
||||
sx={{ borderRadius: "12px" }}
|
||||
>
|
||||
<ToggleButton value="public" sx={{ width: "140px" }}>
|
||||
<PublicIcon fontSize="small" sx={{ mr: 1 }} />
|
||||
|
||||
@@ -9,12 +9,23 @@ export function AddDescButton({
|
||||
showMore,
|
||||
description,
|
||||
setDescription,
|
||||
buttonVariant,
|
||||
buttonColor,
|
||||
}: {
|
||||
showDescription: boolean;
|
||||
setShowDescription: (b: boolean) => void;
|
||||
showMore: boolean;
|
||||
description: string;
|
||||
setDescription: (d: string) => void;
|
||||
buttonVariant?: "text" | "outlined" | "contained";
|
||||
buttonColor?:
|
||||
| "inherit"
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "success"
|
||||
| "error"
|
||||
| "info"
|
||||
| "warning";
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
@@ -25,11 +36,9 @@ export function AddDescButton({
|
||||
<Button
|
||||
startIcon={<DescriptionIcon />}
|
||||
onClick={() => setShowDescription(true)}
|
||||
size="small"
|
||||
sx={{
|
||||
textTransform: "none",
|
||||
color: "text.secondary",
|
||||
}}
|
||||
size="medium"
|
||||
variant={buttonVariant}
|
||||
color={buttonColor}
|
||||
>
|
||||
{t("event.form.addDescription")}
|
||||
</Button>
|
||||
@@ -40,6 +49,7 @@ export function AddDescButton({
|
||||
<FieldWithLabel
|
||||
label={t("event.form.description")}
|
||||
isExpanded={showMore}
|
||||
sx={{ padding: 0, margin: 0 }}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
@@ -57,6 +67,7 @@ export function AddDescButton({
|
||||
"& .MuiInputBase-root": {
|
||||
maxHeight: "33%",
|
||||
overflowY: "auto",
|
||||
padding: 0,
|
||||
},
|
||||
"& textarea": {
|
||||
resize: "vertical",
|
||||
|
||||
@@ -166,7 +166,7 @@ export function EventChip({
|
||||
{startTime}
|
||||
</Typography>
|
||||
)}
|
||||
{DisplayedIcons(IconDisplayed)}
|
||||
{DisplayedIcons(IconDisplayed, titleStyle.color)}
|
||||
<Typography variant="body2" noWrap style={titleStyle}>
|
||||
{event.title}
|
||||
</Typography>
|
||||
|
||||
@@ -156,28 +156,37 @@ export function getCardStyle(
|
||||
}
|
||||
}
|
||||
|
||||
export function DisplayedIcons(IconDisplayed: IconDisplayConfig) {
|
||||
export function DisplayedIcons(
|
||||
IconDisplayed: IconDisplayConfig,
|
||||
iconColor?: string
|
||||
) {
|
||||
if (!Object.values(IconDisplayed).find((b) => b === true)) return;
|
||||
const iconStyle: React.CSSProperties = {
|
||||
fontSize: "15px",
|
||||
color: iconColor || "inherit",
|
||||
marginRight: 2,
|
||||
};
|
||||
return (
|
||||
<Box
|
||||
<span
|
||||
className="event-chip-icons"
|
||||
style={{
|
||||
display: "flex",
|
||||
display: "inline-flex",
|
||||
flexDirection: "row",
|
||||
gap: "1px",
|
||||
color: iconColor || "inherit",
|
||||
margin: 0,
|
||||
marginRight: "4px",
|
||||
fontFamily: "inherit",
|
||||
fontWeight: "inherit",
|
||||
lineHeight: "inherit",
|
||||
letterSpacing: "inherit",
|
||||
}}
|
||||
>
|
||||
{IconDisplayed.needAction && (
|
||||
<HelpOutlineIcon style={{ fontSize: "15px" }} />
|
||||
)}
|
||||
{IconDisplayed.declined && <CancelIcon style={{ fontSize: "15px" }} />}
|
||||
{IconDisplayed.tentative && (
|
||||
<HelpOutlineIcon style={{ fontSize: "15px" }} />
|
||||
)}
|
||||
{IconDisplayed.private && (
|
||||
<LockOutlineIcon style={{ fontSize: "15px" }} />
|
||||
)}
|
||||
</Box>
|
||||
{IconDisplayed.needAction && <HelpOutlineIcon style={iconStyle} />}
|
||||
{IconDisplayed.declined && <CancelIcon style={iconStyle} />}
|
||||
{IconDisplayed.tentative && <HelpOutlineIcon style={iconStyle} />}
|
||||
{IconDisplayed.private && <LockOutlineIcon style={iconStyle} />}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ContentCopy as CopyIcon,
|
||||
Close as DeleteIcon,
|
||||
} from "@mui/icons-material";
|
||||
import iconCamera from "../../static/images/icon-camera.svg";
|
||||
import AttendeeSelector from "../Attendees/AttendeeSearch";
|
||||
import RepeatEvent from "./EventRepeat";
|
||||
import { RepetitionObject } from "../../features/Events/EventsTypes";
|
||||
@@ -446,6 +447,8 @@ export default function EventFormFields({
|
||||
showMore={showMore}
|
||||
description={description}
|
||||
setDescription={setDescription}
|
||||
buttonVariant="contained"
|
||||
buttonColor="secondary"
|
||||
/>
|
||||
|
||||
<FieldWithLabel label={t("event.form.dateTime")} isExpanded={showMore}>
|
||||
@@ -555,12 +558,15 @@ export default function EventFormFields({
|
||||
>
|
||||
<Box display="flex" gap={1} alignItems="center">
|
||||
<Button
|
||||
startIcon={<VideocamIcon />}
|
||||
startIcon={
|
||||
<img src={iconCamera} alt="camera" width={24} height={24} />
|
||||
}
|
||||
onClick={handleAddVideoConference}
|
||||
size="medium"
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
sx={{
|
||||
textTransform: "none",
|
||||
color: "text.secondary",
|
||||
borderRadius: "4px",
|
||||
display: hasVideoConference ? "none" : "flex",
|
||||
}}
|
||||
>
|
||||
@@ -570,12 +576,15 @@ export default function EventFormFields({
|
||||
{hasVideoConference && meetingLink && (
|
||||
<>
|
||||
<Button
|
||||
startIcon={<VideocamIcon />}
|
||||
startIcon={
|
||||
<img src={iconCamera} alt="camera" width={24} height={24} />
|
||||
}
|
||||
onClick={() => window.open(meetingLink, "_blank")}
|
||||
size="medium"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
sx={{
|
||||
textTransform: "none",
|
||||
borderRadius: "4px",
|
||||
mr: 1,
|
||||
}}
|
||||
>
|
||||
@@ -716,14 +725,14 @@ export default function EventFormFields({
|
||||
setEventClass(newValue);
|
||||
}
|
||||
}}
|
||||
size="small"
|
||||
size="medium"
|
||||
>
|
||||
<ToggleButton value="PUBLIC" sx={{ width: "140px" }}>
|
||||
<PublicIcon sx={{ mr: 1, fontSize: "16px" }} />
|
||||
<ToggleButton value="PUBLIC" sx={{ minWidth: "160px" }}>
|
||||
<PublicIcon sx={{ mr: 1 }} />
|
||||
{t("event.form.visibleAll")}
|
||||
</ToggleButton>
|
||||
<ToggleButton value="PRIVATE" sx={{ width: "140px" }}>
|
||||
<LockIcon sx={{ mr: 1, fontSize: "16px" }} />
|
||||
<ToggleButton value="PRIVATE" sx={{ minWidth: "160px" }}>
|
||||
<LockIcon sx={{ mr: 1 }} />
|
||||
{t("event.form.visibleParticipants")}
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { Box, Typography } from "@linagora/twake-mui";
|
||||
import { Box, Typography, SxProps, Theme } from "@linagora/twake-mui";
|
||||
|
||||
/**
|
||||
* Helper component for field with label
|
||||
@@ -10,15 +10,17 @@ export const FieldWithLabel = React.memo(
|
||||
label,
|
||||
isExpanded,
|
||||
children,
|
||||
sx,
|
||||
}: {
|
||||
label: string | React.ReactNode;
|
||||
isExpanded: boolean;
|
||||
children: React.ReactNode;
|
||||
sx?: SxProps<Theme>;
|
||||
}) => {
|
||||
if (!isExpanded) {
|
||||
// Normal mode: label on top
|
||||
return (
|
||||
<Box>
|
||||
<Box sx={sx}>
|
||||
<Typography
|
||||
component="div"
|
||||
sx={{
|
||||
@@ -37,7 +39,7 @@ export const FieldWithLabel = React.memo(
|
||||
|
||||
// Extended mode: label on left
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
<Box display="flex" alignItems="center" sx={sx}>
|
||||
<Typography
|
||||
component="div"
|
||||
sx={{
|
||||
|
||||
@@ -171,23 +171,30 @@ export function Menubar({
|
||||
<div className="navigation-controls">
|
||||
<ButtonGroup
|
||||
variant="outlined"
|
||||
size="small"
|
||||
size="medium"
|
||||
sx={{
|
||||
height: "43px",
|
||||
"& .MuiButton-root": {
|
||||
color: "#525256",
|
||||
borderColor: "#AEAEC0",
|
||||
"& button:first-of-type": {
|
||||
borderRadius: "12px 0 0 12px",
|
||||
},
|
||||
"& button:last-of-type": {
|
||||
borderRadius: "0 12px 12px 0",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Button onClick={() => handleNavigation("prev")}>
|
||||
<ChevronLeftIcon />
|
||||
<Button
|
||||
sx={{ width: 20 }}
|
||||
onClick={() => handleNavigation("prev")}
|
||||
>
|
||||
<ChevronLeftIcon sx={{ height: 20 }} />
|
||||
</Button>
|
||||
<Button onClick={() => handleNavigation("today")}>
|
||||
{t("menubar.today")}
|
||||
</Button>
|
||||
<Button onClick={() => handleNavigation("next")}>
|
||||
<ChevronRightIcon />
|
||||
<Button
|
||||
sx={{ width: 20 }}
|
||||
onClick={() => handleNavigation("next")}
|
||||
>
|
||||
<ChevronRightIcon sx={{ height: 20 }} />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
|
||||
@@ -47,7 +47,7 @@ export function RSVPButton({
|
||||
? rsvpColor[rsvpValue]
|
||||
: "primary"
|
||||
}
|
||||
size="large"
|
||||
size="medium"
|
||||
sx={{ borderRadius: "50px" }}
|
||||
onClick={() =>
|
||||
handleRSVPClick(
|
||||
|
||||
@@ -18,7 +18,6 @@ import EventPopover from "./EventModal";
|
||||
import {
|
||||
Button,
|
||||
Chip,
|
||||
DialogActions,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
@@ -305,180 +304,150 @@ export default function EventPreviewModal({
|
||||
actionsJustifyContent="center"
|
||||
style={{ overflow: "auto" }}
|
||||
title={
|
||||
<>
|
||||
<DialogActions>
|
||||
<Box>
|
||||
{(window as any).DEBUG && (
|
||||
<IconButton
|
||||
onClick={async () => {
|
||||
const icsContent = await dlEvent(event);
|
||||
const blob = new Blob([icsContent], {
|
||||
type: "text/calendar",
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="flex-end"
|
||||
alignItems="center"
|
||||
gap={0.5}
|
||||
width="100%"
|
||||
>
|
||||
{(window as any).DEBUG && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={async () => {
|
||||
let url: string | null = null;
|
||||
try {
|
||||
const icsContent = await dlEvent(event);
|
||||
const blob = new Blob([icsContent], {
|
||||
type: "text/calendar",
|
||||
});
|
||||
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);
|
||||
}}
|
||||
>
|
||||
<FileDownloadOutlinedIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
{isOrganizer && isOwn && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
if (isRecurring) {
|
||||
setAfterChoiceFunc(() => () => {
|
||||
setHidePreview(true);
|
||||
setOpenUpdateModal(true);
|
||||
});
|
||||
setOpenEditModePopup("edit");
|
||||
} else {
|
||||
setHidePreview(true);
|
||||
setOpenUpdateModal(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
{((event.class !== "PRIVATE" && !isOwn) || isOwn) && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(e) => setToggleActionMenu(e.currentTarget)}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
<Menu
|
||||
open={Boolean(toggleActionMenu)}
|
||||
onClose={() => setToggleActionMenu(null)}
|
||||
anchorEl={toggleActionMenu}
|
||||
>
|
||||
{mailSpaUrl && attendees.length > 0 && (
|
||||
<MenuItem
|
||||
onClick={() =>
|
||||
window.open(
|
||||
`${mailSpaUrl}/mailto/?uri=mailto:${event.attendee
|
||||
.map((a) => a.cal_address)
|
||||
.filter((mail) => mail !== user.email)
|
||||
.join(
|
||||
","
|
||||
)}?subject=${encodeURIComponent(event.title ?? "")}`
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("eventPreview.emailAttendees")}
|
||||
</MenuItem>
|
||||
)}
|
||||
<EventDuplication
|
||||
event={event}
|
||||
onClose={() => setToggleActionMenu(null)}
|
||||
onOpenDuplicate={() => {
|
||||
setToggleActionMenu(null);
|
||||
setHidePreview(true);
|
||||
setOpenDuplicateModal(true);
|
||||
}}
|
||||
/>
|
||||
{isOrganizer && (
|
||||
<MenuItem
|
||||
onClick={async () => {
|
||||
if (isRecurring) {
|
||||
setAfterChoiceFunc(
|
||||
() => (typeOfAction?: "solo" | "all" | undefined) =>
|
||||
handleDelete(
|
||||
isRecurring,
|
||||
typeOfAction,
|
||||
onClose,
|
||||
dispatch,
|
||||
calendar,
|
||||
event,
|
||||
calId,
|
||||
eventId
|
||||
)
|
||||
);
|
||||
setOpenEditModePopup("delete");
|
||||
} else {
|
||||
onClose({}, "backdropClick");
|
||||
try {
|
||||
const result = await dispatch(
|
||||
deleteEventAsync({
|
||||
calId,
|
||||
eventId,
|
||||
eventURL: event.URL,
|
||||
})
|
||||
);
|
||||
|
||||
// For compatibility with tests that may not mock unwrap
|
||||
if (result && typeof result.unwrap === "function") {
|
||||
await result.unwrap();
|
||||
}
|
||||
|
||||
updateTempList();
|
||||
} catch (error) {
|
||||
console.error("Failed to delete event:", error);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("eventPreview.deleteEvent")}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Menu>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => onClose({}, "backdropClick")}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</DialogActions>
|
||||
<Box display="flex" flexDirection="row">
|
||||
{event.class === "PRIVATE" &&
|
||||
(isOwn ? (
|
||||
<Tooltip
|
||||
title={t("eventPreview.privateEvent.tooltipOwn")}
|
||||
placement="top"
|
||||
>
|
||||
<LockOutlineIcon />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<LockOutlineIcon />
|
||||
))}
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
fontSize: "24px",
|
||||
fontWeight: 600,
|
||||
wordBreak: "break-word",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = `${eventId}.ics`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
} catch (error) {
|
||||
console.error("Failed to download ICS file:", error);
|
||||
} finally {
|
||||
if (url) URL.revokeObjectURL(url);
|
||||
}
|
||||
}}
|
||||
gutterBottom
|
||||
>
|
||||
{formatEventChipTitle(event, t)}
|
||||
</Typography>
|
||||
{event.transp === "TRANSPARENT" && (
|
||||
<Tooltip title={t("eventPreview.free.tooltip")} placement="top">
|
||||
<Chip
|
||||
icon={<CircleIcon color="success" fontSize="small" />}
|
||||
label={t("eventPreview.free.label")}
|
||||
/>
|
||||
</Tooltip>
|
||||
<FileDownloadOutlinedIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
{isOrganizer && isOwn && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
if (isRecurring) {
|
||||
setAfterChoiceFunc(() => () => {
|
||||
setHidePreview(true);
|
||||
setOpenUpdateModal(true);
|
||||
});
|
||||
setOpenEditModePopup("edit");
|
||||
} else {
|
||||
setHidePreview(true);
|
||||
setOpenUpdateModal(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
{((event.class !== "PRIVATE" && !isOwn) || isOwn) && (
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(e) => setToggleActionMenu(e.currentTarget)}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
<Menu
|
||||
open={Boolean(toggleActionMenu)}
|
||||
onClose={() => setToggleActionMenu(null)}
|
||||
anchorEl={toggleActionMenu}
|
||||
>
|
||||
{mailSpaUrl && attendees.length > 0 && (
|
||||
<MenuItem
|
||||
onClick={() =>
|
||||
window.open(
|
||||
`${mailSpaUrl}/mailto/?uri=mailto:${attendees
|
||||
.map((a) => a.cal_address)
|
||||
.filter((mail) => mail !== user.email)
|
||||
.join(
|
||||
","
|
||||
)}?subject=${encodeURIComponent(event.title ?? "")}`
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("eventPreview.emailAttendees")}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Box>
|
||||
<Typography color="text.secondaryContainer" gutterBottom>
|
||||
{formatDate(event.start, t, timezone, event.allday)}
|
||||
{event.end &&
|
||||
formatEnd(event.start, event.end, t, timezone, event.allday) &&
|
||||
` – ${formatEnd(event.start, event.end, t, timezone, event.allday)} ${!event.allday ? getTimezoneOffset(timezone, new Date(event.start)) : ""}`}
|
||||
</Typography>
|
||||
</>
|
||||
<EventDuplication
|
||||
event={event}
|
||||
onClose={() => setToggleActionMenu(null)}
|
||||
onOpenDuplicate={() => {
|
||||
setToggleActionMenu(null);
|
||||
setHidePreview(true);
|
||||
setOpenDuplicateModal(true);
|
||||
}}
|
||||
/>
|
||||
{isOrganizer && (
|
||||
<MenuItem
|
||||
onClick={async () => {
|
||||
if (isRecurring) {
|
||||
setAfterChoiceFunc(
|
||||
() => (typeOfAction?: "solo" | "all" | undefined) =>
|
||||
handleDelete(
|
||||
isRecurring,
|
||||
typeOfAction,
|
||||
onClose,
|
||||
dispatch,
|
||||
calendar,
|
||||
event,
|
||||
calId,
|
||||
eventId
|
||||
)
|
||||
);
|
||||
setOpenEditModePopup("delete");
|
||||
} else {
|
||||
onClose({}, "backdropClick");
|
||||
try {
|
||||
const result = await dispatch(
|
||||
deleteEventAsync({
|
||||
calId,
|
||||
eventId,
|
||||
eventURL: event.URL,
|
||||
})
|
||||
);
|
||||
|
||||
// For compatibility with tests that may not mock unwrap
|
||||
if (result && typeof result.unwrap === "function") {
|
||||
await result.unwrap();
|
||||
}
|
||||
|
||||
await updateTempList();
|
||||
} catch (error) {
|
||||
console.error("Failed to delete event:", error);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("eventPreview.deleteEvent")}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Menu>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => onClose({}, "backdropClick")}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
}
|
||||
actions={
|
||||
<AttendanceValidation
|
||||
@@ -490,6 +459,52 @@ export default function EventPreviewModal({
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Box mb={3}>
|
||||
<Box
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
alignItems="center"
|
||||
gap={1}
|
||||
mb={1}
|
||||
>
|
||||
{event.class === "PRIVATE" &&
|
||||
(isOwn ? (
|
||||
<Tooltip
|
||||
title={t("eventPreview.privateEvent.tooltipOwn")}
|
||||
placement="top"
|
||||
>
|
||||
<LockOutlineIcon />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<LockOutlineIcon />
|
||||
))}
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
fontSize: "24px",
|
||||
fontWeight: 600,
|
||||
wordBreak: "break-word",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
}}
|
||||
>
|
||||
{formatEventChipTitle(event, t)}
|
||||
</Typography>
|
||||
{event.transp === "TRANSPARENT" && (
|
||||
<Tooltip title={t("eventPreview.free.tooltip")} placement="top">
|
||||
<Chip
|
||||
icon={<CircleIcon color="success" fontSize="small" />}
|
||||
label={t("eventPreview.free.label")}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
<Typography color="text.secondaryContainer">
|
||||
{formatDate(event.start, t, timezone, event.allday)}
|
||||
{event.end &&
|
||||
formatEnd(event.start, event.end, t, timezone, event.allday) &&
|
||||
` – ${formatEnd(event.start, event.end, t, timezone, event.allday)} ${!event.allday ? getTimezoneOffset(timezone, new Date(event.start)) : ""}`}
|
||||
</Typography>
|
||||
</Box>
|
||||
{((event.class !== "PRIVATE" && !isOwn) || isOwn) && (
|
||||
<>
|
||||
{/* Video */}
|
||||
@@ -503,9 +518,11 @@ export default function EventPreviewModal({
|
||||
content={
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
onClick={() =>
|
||||
window.open(event.x_openpass_videoconference)
|
||||
}
|
||||
sx={{ borderRadius: "4px" }}
|
||||
>
|
||||
{t("eventPreview.joinVideo")}
|
||||
</Button>
|
||||
@@ -701,11 +718,11 @@ export default function EventPreviewModal({
|
||||
)}
|
||||
{/* Calendar color dot */}
|
||||
<Box
|
||||
style={{
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 1,
|
||||
marginBottom: 2,
|
||||
mb: 2,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ minWidth: "25px", marginRight: 2 }}>
|
||||
@@ -775,7 +792,7 @@ export default function EventPreviewModal({
|
||||
calendarRef={{ current: null }}
|
||||
onClose={() => {
|
||||
setOpenDuplicateModal(false);
|
||||
onClose({}, "backdropClick"); // Đóng cả preview modal
|
||||
onClose({}, "backdropClick"); // Close preview modal as well
|
||||
}}
|
||||
event={event}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="24" height="24" rx="10.1356" fill="white"/>
|
||||
<rect width="24" height="24" rx="10.1356" fill="url(#paint0_linear_5774_3576)"/>
|
||||
<g filter="url(#filter0_d_5774_3576)">
|
||||
<path d="M6.2106 11.2587C6.2106 10.2286 6.2106 9.71348 6.40456 9.32001C6.57517 8.9739 6.8474 8.69251 7.18224 8.51616C7.5629 8.31567 8.06121 8.31567 9.05784 8.31567H11.3712C12.3678 8.31567 12.8662 8.31567 13.2468 8.51616C13.5817 8.69251 13.8539 8.9739 14.0245 9.32001C14.2184 9.71348 14.2184 10.2286 14.2184 11.2587V12.7303C14.2184 13.7604 14.2184 14.2755 14.0245 14.669C13.8539 15.0151 13.5817 15.2965 13.2468 15.4728C12.8662 15.6733 12.3678 15.6733 11.3712 15.6733H9.05784C8.06121 15.6733 7.5629 15.6733 7.18224 15.4728C6.8474 15.2965 6.57517 15.0151 6.40456 14.669C6.2106 14.2755 6.2106 13.7604 6.2106 12.7303V11.2587Z" fill="white"/>
|
||||
<path d="M15.1082 10.8363C15.1082 10.7558 15.1082 10.7156 15.1199 10.6799C15.1302 10.6483 15.147 10.6194 15.1692 10.5952C15.1943 10.5678 15.2287 10.549 15.2974 10.5113L16.2875 9.96889C16.6323 9.77997 16.8048 9.6855 16.9454 9.70453C17.0682 9.72113 17.1788 9.78989 17.2505 9.89426C17.3326 10.0138 17.3326 10.2156 17.3326 10.619V13.37C17.3326 13.7734 17.3326 13.9751 17.2505 14.0947C17.1788 14.1991 17.0682 14.2679 16.9454 14.2845C16.8048 14.3035 16.6323 14.209 16.2875 14.0201L15.2974 13.4777C15.2287 13.44 15.1943 13.4212 15.1692 13.3938C15.147 13.3696 15.1302 13.3407 15.1199 13.3091C15.1082 13.2734 15.1082 13.2331 15.1082 13.1527V10.8363Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_5774_3576" x="4.89775" y="7.2654" width="13.7477" height="9.98336" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.26257"/>
|
||||
<feGaussianBlur stdDeviation="0.656424"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5774_3576"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5774_3576" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_5774_3576" x1="2.81482" y1="21.7231" x2="27.4139" y2="-3.61031" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.23798" stop-color="#50C750"/>
|
||||
<stop offset="1" stop-color="#EBFF00"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
Reference in New Issue
Block a user