From 5a7a05b9c041aef279b628eecaef03e0a42b4b01 Mon Sep 17 00:00:00 2001 From: Giorgio Mandolini Date: Wed, 10 Apr 2024 08:32:59 +0200 Subject: [PATCH] refactor: events permissions --- src/lib/components/events/Actions.tsx | 21 +++---------- src/lib/components/events/EventItem.tsx | 34 +++++--------------- src/lib/hooks/useEventPermissions.ts | 42 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 44 deletions(-) create mode 100644 src/lib/hooks/useEventPermissions.ts diff --git a/src/lib/components/events/Actions.tsx b/src/lib/components/events/Actions.tsx index d2408e0..251cf01 100644 --- a/src/lib/components/events/Actions.tsx +++ b/src/lib/components/events/Actions.tsx @@ -1,10 +1,11 @@ import DeleteRounded from "@mui/icons-material/DeleteRounded"; import EditRounded from "@mui/icons-material/EditRounded"; import { Button, Grow, IconButton, Slide } from "@mui/material"; -import { useMemo, useState } from "react"; +import { useState } from "react"; import { EventActions as Actions } from "../../styles/styles"; import { ProcessedEvent } from "../../types"; import useStore from "../../hooks/useStore"; +import useEventPermissions from "../../hooks/useEventPermissions"; interface Props { event: ProcessedEvent; @@ -13,7 +14,7 @@ interface Props { } const EventActions = ({ event, onDelete, onEdit }: Props) => { - const { translations, direction, editable, deletable } = useStore(); + const { translations, direction } = useStore(); const [deleteConfirm, setDeleteConfirm] = useState(false); const handleDelete = () => { @@ -23,21 +24,7 @@ const EventActions = ({ event, onDelete, onEdit }: Props) => { onDelete(); }; - const canDelete = useMemo(() => { - // Priority control to event specific deletable value - if (typeof event.deletable !== "undefined") { - return event.deletable; - } - return deletable; - }, [deletable, event.deletable]); - - const canEdit = useMemo(() => { - // Priority control to event specific deletable value - if (typeof event.editable !== "undefined") { - return event.editable; - } - return editable; - }, [editable, event.editable]); + const { canEdit, canDelete } = useEventPermissions(event); return ( diff --git a/src/lib/components/events/EventItem.tsx b/src/lib/components/events/EventItem.tsx index 8463738..671ff4b 100644 --- a/src/lib/components/events/EventItem.tsx +++ b/src/lib/components/events/EventItem.tsx @@ -9,6 +9,7 @@ import { differenceInDaysOmitTime, getHourFormat } from "../../helpers/generals" import useStore from "../../hooks/useStore"; import useDragAttributes from "../../hooks/useDragAttributes"; import EventItemPopover from "./EventItemPopover"; +import useEventPermissions from "../../hooks/useEventPermissions"; interface EventItemProps { event: ProcessedEvent; @@ -19,17 +20,8 @@ interface EventItemProps { } const EventItem = ({ event, multiday, hasPrev, hasNext, showdate = true }: EventItemProps) => { - const { - direction, - locale, - hourFormat, - eventRenderer, - onEventClick, - view, - draggable, - editable, - disableViewer, - } = useStore(); + const { direction, locale, hourFormat, eventRenderer, onEventClick, view, disableViewer } = + useStore(); const dragProps = useDragAttributes(event); const [anchorEl, setAnchorEl] = useState(null); const [deleteConfirm, setDeleteConfirm] = useState(false); @@ -40,6 +32,8 @@ const EventItem = ({ event, multiday, hasPrev, hasNext, showdate = true }: Event const PrevArrow = direction === "rtl" ? ArrowRightRoundedIcon : ArrowLeftRoundedIcon; const hideDates = differenceInDaysOmitTime(event.start, event.end) <= 0 && event.allDay; + const { canDrag } = useEventPermissions(event); + const triggerViewer = (el?: MouseEvent) => { if (!el?.currentTarget && deleteConfirm) { setDeleteConfirm(false); @@ -47,20 +41,6 @@ const EventItem = ({ event, multiday, hasPrev, hasNext, showdate = true }: Event setAnchorEl(el?.currentTarget || null); }; - const isDraggable = useMemo(() => { - // if Disabled - if (event.disabled || !editable) return false; - - // global-wise isDraggable - let canDrag = typeof draggable !== "undefined" ? draggable : true; - - // Override by event-wise - if (typeof event.draggable !== "undefined") { - canDrag = event.draggable; - } - return canDrag; - }, [draggable, editable, event.disabled, event.draggable]); - const renderEvent = useMemo(() => { // Check if has custom render event method // only applicable to non-multiday events and not in month-view @@ -143,14 +123,14 @@ const EventItem = ({ event, multiday, hasPrev, hasNext, showdate = true }: Event focusRipple disabled={disableViewer || event.disabled} > -
+
{item}
); // eslint-disable-next-line - }, [hasPrev, hasNext, event, isDraggable, locale, theme.palette]); + }, [hasPrev, hasNext, event, canDrag, locale, theme.palette]); return ( diff --git a/src/lib/hooks/useEventPermissions.ts b/src/lib/hooks/useEventPermissions.ts new file mode 100644 index 0000000..268f09a --- /dev/null +++ b/src/lib/hooks/useEventPermissions.ts @@ -0,0 +1,42 @@ +import { useMemo } from "react"; +import { ProcessedEvent } from "../types"; +import useStore from "./useStore"; + +const useEventPermissions = (event: ProcessedEvent) => { + const { editable, deletable, draggable } = useStore(); + + const canEdit = useMemo(() => { + // Priority control to event specific editable value + if (typeof event.editable !== "undefined") { + return event.editable; + } + return editable; + }, [editable, event.editable]); + + const canDelete = useMemo(() => { + // Priority control to event specific deletable value + if (typeof event.deletable !== "undefined") { + return event.deletable; + } + return deletable; + }, [deletable, event.deletable]); + + const canDrag = useMemo(() => { + if (!canEdit) { + return; + } + // Priority control to event specific draggable value + if (typeof event.draggable !== "undefined") { + return event.draggable; + } + return draggable; + }, [draggable, event.draggable, canEdit]); + + return { + canEdit, + canDelete, + canDrag, + }; +}; + +export default useEventPermissions;