ISSUE-845 Edit in XXX calendar
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Box, IconButton } from '@linagora/twake-mui'
|
import { Box, IconButton, Tooltip } from '@linagora/twake-mui'
|
||||||
import CloseIcon from '@mui/icons-material/Close'
|
import CloseIcon from '@mui/icons-material/Close'
|
||||||
import EditIcon from '@mui/icons-material/Edit'
|
import EditIcon from '@mui/icons-material/Edit'
|
||||||
import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined'
|
import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined'
|
||||||
@@ -13,23 +13,26 @@ interface EventPreviewHeaderProps {
|
|||||||
isOwn: boolean
|
isOwn: boolean
|
||||||
isWriteDelegated: boolean
|
isWriteDelegated: boolean
|
||||||
isNotPrivate: boolean
|
isNotPrivate: boolean
|
||||||
|
canEdit: boolean
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onEdit: () => void
|
onEdit: () => void
|
||||||
onMoreClick: (e: React.MouseEvent<HTMLElement>) => void
|
onMoreClick: (e: React.MouseEvent<HTMLElement>) => void
|
||||||
|
onEditInOrganizerCalendar?: () => void
|
||||||
|
editInOrganizerCalendarTooltip?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EventPreviewHeader({
|
export function EventPreviewHeader({
|
||||||
event,
|
event,
|
||||||
eventId,
|
eventId,
|
||||||
isOrganizer,
|
|
||||||
isOwn,
|
isOwn,
|
||||||
isWriteDelegated,
|
|
||||||
isNotPrivate,
|
isNotPrivate,
|
||||||
|
canEdit,
|
||||||
onClose,
|
onClose,
|
||||||
onEdit,
|
onEdit,
|
||||||
onMoreClick
|
onMoreClick,
|
||||||
|
onEditInOrganizerCalendar,
|
||||||
|
editInOrganizerCalendarTooltip
|
||||||
}: EventPreviewHeaderProps) {
|
}: EventPreviewHeaderProps) {
|
||||||
const canEdit = isOrganizer && (isOwn || (isWriteDelegated && isNotPrivate))
|
|
||||||
const canSeeMore = isNotPrivate || isOwn
|
const canSeeMore = isNotPrivate || isOwn
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -70,6 +73,13 @@ export function EventPreviewHeader({
|
|||||||
<EditIcon />
|
<EditIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
|
{!canEdit && onEditInOrganizerCalendar && (
|
||||||
|
<Tooltip title={editInOrganizerCalendarTooltip} placement="top">
|
||||||
|
<IconButton size="small" onClick={onEditInOrganizerCalendar}>
|
||||||
|
<EditIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
{canSeeMore && (
|
{canSeeMore && (
|
||||||
<IconButton size="small" onClick={onMoreClick}>
|
<IconButton size="small" onClick={onMoreClick}>
|
||||||
<MoreVertIcon />
|
<MoreVertIcon />
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ export default function EventPreviewModal({
|
|||||||
isWriteDelegated,
|
isWriteDelegated,
|
||||||
isOrganizer,
|
isOrganizer,
|
||||||
isNotPrivate,
|
isNotPrivate,
|
||||||
|
canEdit,
|
||||||
|
organizerWritableCalendar,
|
||||||
openUpdateModal,
|
openUpdateModal,
|
||||||
setOpenUpdateModal,
|
setOpenUpdateModal,
|
||||||
openDuplicateModal,
|
openDuplicateModal,
|
||||||
@@ -51,6 +53,7 @@ export default function EventPreviewModal({
|
|||||||
setHidePreview,
|
setHidePreview,
|
||||||
toggleActionMenu,
|
toggleActionMenu,
|
||||||
setToggleActionMenu,
|
setToggleActionMenu,
|
||||||
|
updateModalCalId,
|
||||||
openEditModePopup,
|
openEditModePopup,
|
||||||
setOpenEditModePopup,
|
setOpenEditModePopup,
|
||||||
setTypeOfAction,
|
setTypeOfAction,
|
||||||
@@ -58,6 +61,7 @@ export default function EventPreviewModal({
|
|||||||
setAfterChoiceFunc,
|
setAfterChoiceFunc,
|
||||||
resolvedTypeOfAction,
|
resolvedTypeOfAction,
|
||||||
handleEditClick,
|
handleEditClick,
|
||||||
|
handleEditInOrganizerCalendar,
|
||||||
handleDeleteClick,
|
handleDeleteClick,
|
||||||
handleDuplicateClick
|
handleDuplicateClick
|
||||||
} = useEventPreviewState(eventId, calId, tempEvent, open, onClose)
|
} = useEventPreviewState(eventId, calId, tempEvent, open, onClose)
|
||||||
@@ -101,9 +105,23 @@ export default function EventPreviewModal({
|
|||||||
isOwn={isOwn}
|
isOwn={isOwn}
|
||||||
isWriteDelegated={isWriteDelegated}
|
isWriteDelegated={isWriteDelegated}
|
||||||
isNotPrivate={isNotPrivate}
|
isNotPrivate={isNotPrivate}
|
||||||
|
canEdit={canEdit}
|
||||||
onClose={() => onClose({}, 'backdropClick')}
|
onClose={() => onClose({}, 'backdropClick')}
|
||||||
onEdit={handleEditClick}
|
onEdit={handleEditClick}
|
||||||
onMoreClick={e => setToggleActionMenu(e.currentTarget)}
|
onMoreClick={e => setToggleActionMenu(e.currentTarget)}
|
||||||
|
onEditInOrganizerCalendar={
|
||||||
|
organizerWritableCalendar
|
||||||
|
? handleEditInOrganizerCalendar
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
editInOrganizerCalendarTooltip={
|
||||||
|
organizerWritableCalendar
|
||||||
|
? t('eventPreview.editInOrganizerCalendar').replace(
|
||||||
|
'%{calendarName}',
|
||||||
|
organizerWritableCalendar.name
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
actions={
|
actions={
|
||||||
@@ -209,7 +227,7 @@ export default function EventPreviewModal({
|
|||||||
onClose({}, 'backdropClick')
|
onClose({}, 'backdropClick')
|
||||||
}}
|
}}
|
||||||
eventId={eventId}
|
eventId={eventId}
|
||||||
calId={calId}
|
calId={updateModalCalId}
|
||||||
typeOfAction={resolvedTypeOfAction}
|
typeOfAction={resolvedTypeOfAction}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useAppDispatch, useAppSelector } from '@/app/hooks'
|
import { useAppDispatch, useAppSelector } from '@/app/hooks'
|
||||||
|
import { Calendar } from '@/features/Calendars/CalendarTypes'
|
||||||
import { assertThunkSuccess } from '@/utils/assertThunkSuccess'
|
import { assertThunkSuccess } from '@/utils/assertThunkSuccess'
|
||||||
import { getEffectiveEmail } from '@/utils/getEffectiveEmail'
|
import { getEffectiveEmail } from '@/utils/getEffectiveEmail'
|
||||||
import { isEventOrganiser } from '@/utils/isEventOrganiser'
|
import { isEventOrganiser } from '@/utils/isEventOrganiser'
|
||||||
@@ -31,6 +32,7 @@ export function useEventPreviewState(
|
|||||||
const [openDuplicateModal, setOpenDuplicateModal] = useState(false)
|
const [openDuplicateModal, setOpenDuplicateModal] = useState(false)
|
||||||
const [hidePreview, setHidePreview] = useState(false)
|
const [hidePreview, setHidePreview] = useState(false)
|
||||||
const [toggleActionMenu, setToggleActionMenu] = useState<Element | null>(null)
|
const [toggleActionMenu, setToggleActionMenu] = useState<Element | null>(null)
|
||||||
|
const [updateModalCalId, setUpdateModalCalId] = useState(calId)
|
||||||
|
|
||||||
// Recurring event handling
|
// Recurring event handling
|
||||||
const [openEditModePopup, setOpenEditModePopup] = useState<string | null>(
|
const [openEditModePopup, setOpenEditModePopup] = useState<string | null>(
|
||||||
@@ -68,6 +70,22 @@ export function useEventPreviewState(
|
|||||||
const isNotPrivate =
|
const isNotPrivate =
|
||||||
event?.class !== 'PRIVATE' && event?.class !== 'CONFIDENTIAL'
|
event?.class !== 'PRIVATE' && event?.class !== 'CONFIDENTIAL'
|
||||||
|
|
||||||
|
const canEdit = isOrganizer && (isOwn || (isWriteDelegated && isNotPrivate))
|
||||||
|
|
||||||
|
// If the user cannot edit here but has write access to the organizer's delegated
|
||||||
|
// calendar, surface a shortcut so they don't have to hunt for the source event.
|
||||||
|
const organizerEmail = event?.organizer?.cal_address?.toLowerCase()
|
||||||
|
const organizerWritableCalendar: Calendar | undefined =
|
||||||
|
!canEdit && organizerEmail
|
||||||
|
? Object.values(calendars.list).find(
|
||||||
|
cal =>
|
||||||
|
cal.delegated &&
|
||||||
|
cal.access?.write &&
|
||||||
|
cal.owner?.emails?.some(e => e.toLowerCase() === organizerEmail) &&
|
||||||
|
cal.events[eventId] !== undefined
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
|
||||||
const contextualizedEvent =
|
const contextualizedEvent =
|
||||||
event && calendar && user ? createEventContext(event, calendar, user) : null
|
event && calendar && user ? createEventContext(event, calendar, user) : null
|
||||||
|
|
||||||
@@ -97,6 +115,22 @@ export function useEventPreviewState(
|
|||||||
|
|
||||||
// Action handlers
|
// Action handlers
|
||||||
const handleEditClick = () => {
|
const handleEditClick = () => {
|
||||||
|
setUpdateModalCalId(calId)
|
||||||
|
if (isRecurring) {
|
||||||
|
setAfterChoiceFunc(() => () => {
|
||||||
|
setHidePreview(true)
|
||||||
|
setOpenUpdateModal(true)
|
||||||
|
})
|
||||||
|
setOpenEditModePopup('edit')
|
||||||
|
} else {
|
||||||
|
setHidePreview(true)
|
||||||
|
setOpenUpdateModal(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEditInOrganizerCalendar = () => {
|
||||||
|
if (!organizerWritableCalendar) return
|
||||||
|
setUpdateModalCalId(organizerWritableCalendar.id)
|
||||||
if (isRecurring) {
|
if (isRecurring) {
|
||||||
setAfterChoiceFunc(() => () => {
|
setAfterChoiceFunc(() => () => {
|
||||||
setHidePreview(true)
|
setHidePreview(true)
|
||||||
@@ -158,6 +192,8 @@ export function useEventPreviewState(
|
|||||||
isWriteDelegated,
|
isWriteDelegated,
|
||||||
isOrganizer,
|
isOrganizer,
|
||||||
isNotPrivate,
|
isNotPrivate,
|
||||||
|
canEdit,
|
||||||
|
organizerWritableCalendar,
|
||||||
|
|
||||||
// Modal state
|
// Modal state
|
||||||
openUpdateModal,
|
openUpdateModal,
|
||||||
@@ -168,6 +204,7 @@ export function useEventPreviewState(
|
|||||||
setHidePreview,
|
setHidePreview,
|
||||||
toggleActionMenu,
|
toggleActionMenu,
|
||||||
setToggleActionMenu,
|
setToggleActionMenu,
|
||||||
|
updateModalCalId,
|
||||||
|
|
||||||
// Recurring state
|
// Recurring state
|
||||||
openEditModePopup,
|
openEditModePopup,
|
||||||
@@ -180,6 +217,7 @@ export function useEventPreviewState(
|
|||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
handleEditClick,
|
handleEditClick,
|
||||||
|
handleEditInOrganizerCalendar,
|
||||||
handleDeleteClick,
|
handleDeleteClick,
|
||||||
handleDuplicateClick,
|
handleDuplicateClick,
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,7 @@
|
|||||||
},
|
},
|
||||||
"showMore": "Show more",
|
"showMore": "Show more",
|
||||||
"showLess": "Show less",
|
"showLess": "Show less",
|
||||||
|
"editInOrganizerCalendar": "Edit in %{calendarName}",
|
||||||
"joinVideo": "Join the video conference",
|
"joinVideo": "Join the video conference",
|
||||||
"joinVideoShort": "Join",
|
"joinVideoShort": "Join",
|
||||||
"guests": "%{count} guests",
|
"guests": "%{count} guests",
|
||||||
|
|||||||
@@ -320,6 +320,7 @@
|
|||||||
},
|
},
|
||||||
"showMore": "Afficher plus",
|
"showMore": "Afficher plus",
|
||||||
"showLess": "Afficher moins",
|
"showLess": "Afficher moins",
|
||||||
|
"editInOrganizerCalendar": "Modifier dans %{calendarName}",
|
||||||
"joinVideo": "Rejoindre la visioconférence",
|
"joinVideo": "Rejoindre la visioconférence",
|
||||||
"joinVideoShort": "Rejoindre",
|
"joinVideoShort": "Rejoindre",
|
||||||
"guests": "%{count} participants",
|
"guests": "%{count} participants",
|
||||||
|
|||||||
@@ -320,6 +320,7 @@
|
|||||||
},
|
},
|
||||||
"showMore": "Показать больше",
|
"showMore": "Показать больше",
|
||||||
"showLess": "Показать меньше",
|
"showLess": "Показать меньше",
|
||||||
|
"editInOrganizerCalendar": "Редактировать в %{calendarName}",
|
||||||
"joinVideo": "Присоединиться к видеоконференции",
|
"joinVideo": "Присоединиться к видеоконференции",
|
||||||
"joinVideoShort": "Присоединиться",
|
"joinVideoShort": "Присоединиться",
|
||||||
"guests": "%{count} гостей",
|
"guests": "%{count} гостей",
|
||||||
|
|||||||
@@ -318,6 +318,7 @@
|
|||||||
},
|
},
|
||||||
"showMore": "Xem thêm",
|
"showMore": "Xem thêm",
|
||||||
"showLess": "Thu gọn",
|
"showLess": "Thu gọn",
|
||||||
|
"editInOrganizerCalendar": "Chỉnh sửa trong %{calendarName}",
|
||||||
"joinVideo": "Tham gia cuộc họp video",
|
"joinVideo": "Tham gia cuộc họp video",
|
||||||
"joinVideoShort": "Tham gia",
|
"joinVideoShort": "Tham gia",
|
||||||
"guests": "%{count} khách",
|
"guests": "%{count} khách",
|
||||||
|
|||||||
Reference in New Issue
Block a user