diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 6fc6a2a0e8..da4c6a0723 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import i18n from "../i18n/i18n"; @@ -23,6 +23,7 @@ import { UserInfoState } from "../slices/userInfoSlice"; import { Tooltip } from "./shared/Tooltip"; import { HiTranslate } from "react-icons/hi"; import { IconContext } from "react-icons"; +import { ModalHandle } from "./shared/modals/Modal"; // References for detecting a click outside of the container of the dropdown menus const containerLang = React.createRef(); @@ -52,8 +53,8 @@ const Header = () => { const [displayMenuUser, setMenuUser] = useState(false); const [displayMenuNotify, setMenuNotify] = useState(false); const [displayMenuHelp, setMenuHelp] = useState(false); - const [displayRegistrationModal, setRegistrationModal] = useState(false); - const [displayHotKeyCheatSheet, setHotKeyCheatSheet] = useState(false); + const registrationModalRef = useRef(null); + const hotKeyCheatSheetModalRef = useRef(null); const healthStatus = useAppSelector(state => getHealthStatus(state)); const errorCounter = useAppSelector(state => getErrorCount(state)); @@ -69,11 +70,7 @@ const Header = () => { }; const showRegistrationModal = () => { - setRegistrationModal(true); - }; - - const hideRegistrationModal = () => { - setRegistrationModal(false); + registrationModalRef.current?.open() }; const redirectToServices = async () => { @@ -85,15 +82,15 @@ const Header = () => { }; const showHotKeyCheatSheet = () => { - setHotKeyCheatSheet(true); - }; - - const hideHotKeyCheatSheet = () => { - setHotKeyCheatSheet(false); + hotKeyCheatSheetModalRef.current?.open() }; const toggleHotKeyCheatSheet = () => { - setHotKeyCheatSheet(!displayHotKeyCheatSheet); + if (hotKeyCheatSheetModalRef.current?.isOpen?.()) { + hotKeyCheatSheetModalRef.current?.close?.() + } else { + hotKeyCheatSheetModalRef.current?.open() + } }; useHotkeys( @@ -277,14 +274,10 @@ const Header = () => { {/* Adopters Registration Modal */} - {displayRegistrationModal && ( - - )} + {/* Hotkey Cheat Sheet */} - {displayHotKeyCheatSheet && ( - - )} + ); }; diff --git a/src/components/configuration/Themes.tsx b/src/components/configuration/Themes.tsx index fa4fab200c..f3c51e573c 100644 --- a/src/components/configuration/Themes.tsx +++ b/src/components/configuration/Themes.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import MainNav from "../shared/MainNav"; import { Link } from "react-router-dom"; @@ -20,6 +20,7 @@ import { hasAccess } from "../../utils/utils"; import { getCurrentFilterResource } from "../../selectors/tableFilterSelectors"; import { useAppDispatch, useAppSelector } from "../../store"; import { fetchThemes } from "../../slices/themeSlice"; +import { ModalHandle } from "../shared/modals/Modal"; /** * This component renders the table view of events @@ -31,7 +32,7 @@ const Themes = () => { const currentFilterType = useAppSelector(state => getCurrentFilterResource(state)); const [displayNavigation, setNavigation] = useState(false); - const [displayNewThemesModal, setNewThemesModal] = useState(false); + const newThemesModalRef = useRef(null); const user = useAppSelector(state => getUserInformation(state)); const themes = useAppSelector(state => getTotalThemes(state)); @@ -67,11 +68,11 @@ const Themes = () => { }; const showNewThemesModal = () => { - setNewThemesModal(true); + newThemesModalRef.current?.open(); }; const hideNewThemesModal = () => { - setNewThemesModal(false); + newThemesModalRef.current?.close?.(); }; return ( @@ -79,12 +80,11 @@ const Themes = () => {
{/* Display modal for new series if add series button is clicked */} - { displayNewThemesModal && - - } + {/* Include Burger-button menu*/} diff --git a/src/components/configuration/partials/ThemesActionsCell.tsx b/src/components/configuration/partials/ThemesActionsCell.tsx index 87925b8fb9..6b4a1b9031 100644 --- a/src/components/configuration/partials/ThemesActionsCell.tsx +++ b/src/components/configuration/partials/ThemesActionsCell.tsx @@ -1,7 +1,6 @@ -import React, { useState } from "react"; +import React, { useRef } from "react"; import { useTranslation } from "react-i18next"; import ConfirmModal from "../../shared/ConfirmModal"; -import ThemeDetailsModal from "./wizard/ThemeDetailsModal"; import { fetchThemeDetails, fetchUsage, @@ -11,6 +10,8 @@ import { hasAccess } from "../../../utils/utils"; import { useAppDispatch, useAppSelector } from "../../../store"; import { deleteTheme, ThemeDetailsType } from "../../../slices/themeSlice"; import { Tooltip } from "../../shared/Tooltip"; +import ThemeDetails from "./wizard/ThemeDetails"; +import { Modal, ModalHandle } from "../../shared/modals/Modal"; /** * This component renders the action cells of themes in the table view @@ -23,24 +24,24 @@ const ThemesActionsCell = ({ const { t } = useTranslation(); const dispatch = useAppDispatch(); - const [displayDeleteConfirmation, setDeleteConfirmation] = useState(false); - const [displayThemeDetails, setThemeDetails] = useState(false); + const deleteConfirmationModalRef = useRef(null); + const detailsModalRef = useRef(null); const user = useAppSelector(state => getUserInformation(state)); const hideDeleteConfirmation = () => { - setDeleteConfirmation(false); + deleteConfirmationModalRef.current?.close?.(); }; const hideThemeDetails = () => { - setThemeDetails(false); + detailsModalRef.current?.close?.(); }; const showThemeDetails = async () => { await dispatch(fetchThemeDetails(row.id)); await dispatch(fetchUsage(row.id)); - setThemeDetails(true); + detailsModalRef.current?.open(); }; const deletingTheme = (id: number) => { @@ -59,32 +60,34 @@ const ThemesActionsCell = ({ )} - {displayThemeDetails && ( - - )} + {/* themes details modal */} + + {/* component that manages tabs of theme details modal*/} + + {/* delete themes */} {hasAccess("ROLE_UI_THEMES_DELETE", user) && (
- - {/* component that manages tabs of theme details modal*/} - {/* */} - - - - ); -}; - -export default ThemeDetailsModal; diff --git a/src/components/events/Events.tsx b/src/components/events/Events.tsx index 0e1337a4f6..6c6ddad975 100644 --- a/src/components/events/Events.tsx +++ b/src/components/events/Events.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import cn from "classnames"; import { Link, useLocation } from "react-router-dom"; @@ -43,6 +43,7 @@ import { import { fetchSeries } from "../../slices/seriesSlice"; import EventDetailsModal from "./partials/modals/EventDetailsModal"; import { showModal } from "../../selectors/eventDetailsSelectors"; +import { Modal, ModalHandle } from "../shared/modals/Modal"; // References for detecting a click outside of the container of the dropdown menu const containerAction = React.createRef(); @@ -59,16 +60,11 @@ const Events = () => { const [displayActionMenu, setActionMenu] = useState(false); const [displayNavigation, setNavigation] = useState(false); - const [displayNewEventModal, setNewEventModal] = useState(false); - const [displayDeleteModal, setDeleteModal] = useState(false); - const [displayStartTaskModal, setStartTaskModal] = useState(false); - const [ - displayEditScheduledEventsModal, - setEditScheduledEventsModal, - ] = useState(false); - const [displayEditMetadataEventsModal, setEditMetadataEventsModal] = useState( - false - ); + const newEventModalRef = useRef(null); + const startTaskModalRef = useRef(null); + const deleteModalRef = useRef(null); + const editScheduledEventsModalRef = useRef(null); + const editMetadataEventsModalRef = useRef(null); const user = useAppSelector(state => getUserInformation(state)); const showActions = useAppSelector(state => isShowActions(state)); @@ -149,27 +145,27 @@ const Events = () => { await dispatch(fetchEventMetadata()); await dispatch(fetchAssetUploadOptions()); - setNewEventModal(true); + newEventModalRef.current?.open(); }; const hideNewEventModal = () => { - setNewEventModal(false); + newEventModalRef.current?.close?.(); }; const hideDeleteModal = () => { - setDeleteModal(false); + deleteModalRef.current?.close?.(); }; const hideStartTaskModal = () => { - setStartTaskModal(false); + startTaskModalRef.current?.close?.(); }; const hideEditScheduledEventsModal = () => { - setEditScheduledEventsModal(false); + editScheduledEventsModalRef.current?.close?.(); }; const hideEditMetadataEventsModal = () => { - setEditMetadataEventsModal(false); + editMetadataEventsModalRef.current?.close?.(); }; useHotkeys( @@ -187,26 +183,48 @@ const Events = () => { { /* Display modal for new event if add event button is clicked */ - !isFetchingAssetUploadOptions && displayNewEventModal && ( + !isFetchingAssetUploadOptions && ( ) } {/* Display bulk actions modal if one is chosen from dropdown */} - {displayDeleteModal && } - - {displayStartTaskModal && } - - {displayEditScheduledEventsModal && ( + + + + + + + + + - )} + - {displayEditMetadataEventsModal && ( + - )} + {/* Include Burger-button menu */} @@ -238,7 +256,7 @@ const Events = () => { )} - +
{hasAccess("ROLE_UI_EVENTS_CREATE", user) && ( )} {hasAccess("ROLE_UI_TASKS_CREATE", user) && (
  • -
  • @@ -281,14 +299,14 @@ const Events = () => { {hasAccess("ROLE_UI_EVENTS_DETAILS_SCHEDULING_EDIT", user) && hasAccess("ROLE_UI_EVENTS_DETAILS_METADATA_EDIT", user) && (
  • -
  • )} {hasAccess("ROLE_UI_EVENTS_DETAILS_METADATA_EDIT", user) && (
  • -
  • diff --git a/src/components/events/Series.tsx b/src/components/events/Series.tsx index 4dcce7f070..7685c8dfcc 100644 --- a/src/components/events/Series.tsx +++ b/src/components/events/Series.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import MainNav from "../shared/MainNav"; import { useTranslation } from "react-i18next"; import cn from "classnames"; @@ -22,9 +22,7 @@ import MainView from "../MainView"; import Footer from "../Footer"; import { getUserInformation } from "../../selectors/userInfoSelectors"; import { hasAccess } from "../../utils/utils"; -import { availableHotkeys } from "../../configs/hotkeysConfig"; import { getCurrentFilterResource } from "../../selectors/tableFilterSelectors"; -import { useHotkeys } from "react-hotkeys-hook"; import { useAppDispatch, useAppSelector } from "../../store"; import { fetchEvents } from "../../slices/eventSlice"; import { @@ -34,6 +32,7 @@ import { showActionsSeries, } from "../../slices/seriesSlice"; import { fetchSeriesDetailsTobiraNew } from "../../slices/seriesSlice"; +import { Modal, ModalHandle } from "../shared/modals/Modal"; // References for detecting a click outside of the container of the dropdown menu const containerAction = React.createRef(); @@ -46,8 +45,8 @@ const Series = () => { const dispatch = useAppDispatch(); const [displayActionMenu, setActionMenu] = useState(false); const [displayNavigation, setNavigation] = useState(false); - const [displayNewSeriesModal, setNewSeriesModal] = useState(false); - const [displayDeleteSeriesModal, setDeleteSeriesModal] = useState(false); + const newSeriesModalRef = useRef(null); + const deleteModalRef = useRef(null); const user = useAppSelector(state => getUserInformation(state)); const currentFilterType = useAppSelector(state => getCurrentFilterResource(state)); @@ -130,39 +129,36 @@ const Series = () => { await dispatch(fetchSeriesThemes()); await dispatch(fetchSeriesDetailsTobiraNew("/")); - setNewSeriesModal(true); + newSeriesModalRef.current?.open(); }; const hideNewSeriesModal = () => { - setNewSeriesModal(false); + newSeriesModalRef.current?.close?.(); }; const hideDeleteModal = () => { - setDeleteSeriesModal(false); + deleteModalRef.current?.close?.(); }; - useHotkeys( - availableHotkeys.general.NEW_SERIES.sequence, - () => showNewSeriesModal(), - { description: t(availableHotkeys.general.NEW_SERIES.description) ?? undefined }, - [showNewSeriesModal] - ); - return ( <>
    {/* Display modal for new series if add series button is clicked */} - { displayNewSeriesModal && - - } - - {displayDeleteSeriesModal && ( + + + - )} + {/* Include Burger-button menu */} @@ -187,7 +183,7 @@ const Series = () => { )} - +
    {hasAccess("ROLE_UI_SERIES_CREATE", user) && ( diff --git a/src/components/events/partials/EventActionCell.tsx b/src/components/events/partials/EventActionCell.tsx index 0654b63cf2..ab7996d6b1 100644 --- a/src/components/events/partials/EventActionCell.tsx +++ b/src/components/events/partials/EventActionCell.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useRef } from "react"; import { useTranslation } from "react-i18next"; import ConfirmModal from "../../shared/ConfirmModal"; import EmbeddingCodeModal from "./modals/EmbeddingCodeModal"; @@ -17,6 +17,7 @@ import { import { Event, deleteEvent } from "../../../slices/eventSlice"; import { Tooltip } from "../../shared/Tooltip"; import { openModal } from "../../../slices/eventDetailsSlice"; +import { Modal, ModalHandle } from "../../shared/modals/Modal"; /** * This component renders the action cells of events in the table view @@ -29,14 +30,14 @@ const EventActionCell = ({ const { t } = useTranslation(); const dispatch = useAppDispatch(); - const [displayDeleteConfirmation, setDeleteConfirmation] = useState(false); - const [displaySeriesDetailsModal, setSeriesDetailsModal] = useState(false); - const [displayEmbeddingCodeModal, setEmbeddingCodeModal] = useState(false); + const deleteConfirmationModalRef = useRef(null); + const seriesDetailsModalRef = useRef(null); + const embeddingCodeModalRef = useRef(null); const user = useAppSelector(state => getUserInformation(state)); const hideDeleteConfirmation = () => { - setDeleteConfirmation(false); + deleteConfirmationModalRef.current?.close?.() }; const deletingEvent = (id: string) => { @@ -44,19 +45,15 @@ const EventActionCell = ({ }; const hideEmbeddingCodeModal = () => { - setEmbeddingCodeModal(false); + embeddingCodeModalRef.current?.close?.(); }; const showEmbeddingCodeModal = () => { - setEmbeddingCodeModal(true); + embeddingCodeModalRef.current?.open(); }; const showSeriesDetailsModal = () => { - setSeriesDetailsModal(true); - }; - - const hideSeriesDetailsModal = () => { - setSeriesDetailsModal(false); + seriesDetailsModalRef.current?.open(); }; const onClickSeriesDetails = async () => { @@ -89,11 +86,11 @@ const EventActionCell = ({ return ( <> - {!!row.series && displaySeriesDetailsModal && ( + {!!row.series && ( )} @@ -122,22 +119,21 @@ const EventActionCell = ({ {hasAccess("ROLE_UI_EVENTS_DELETE", user) && (
    - -
    -
    -
    -
    -
    -

    {t("BULK_ACTIONS.DELETE_EVENTS_WARNING_LINE1")}

    -

    {t("BULK_ACTIONS.DELETE_EVENTS_WARNING_LINE2")}

    -
    - {/*todo: only show if scheduling Authorized*/} -
    -

    {t("BULK_ACTIONS.DELETE.EVENTS.UNAUTHORIZED")}

    -
    +
    +
    +
    +
    +
    +

    {t("BULK_ACTIONS.DELETE_EVENTS_WARNING_LINE1")}

    +

    {t("BULK_ACTIONS.DELETE_EVENTS_WARNING_LINE2")}

    +
    + {/*todo: only show if scheduling Authorized*/} +
    +

    {t("BULK_ACTIONS.DELETE.EVENTS.UNAUTHORIZED")}

    +
    -
    -
    -
    - {t("BULK_ACTIONS.DELETE.EVENTS.DELETE_EVENTS")} -
    - - - - + ))} + +
    +
    +
    +
    + {t("BULK_ACTIONS.DELETE.EVENTS.DELETE_EVENTS")} +
    + + + + + + + + + + {/* Repeat for each marked event*/} + {selectedEvents.map((event, key) => ( + + - - - - - {/* Repeat for each marked event*/} - {selectedEvents.map((event, key) => ( - - - - + + - - ))} - -
    + onChangeAllSelected(e)} + className="select-all-cbox" + /> + {t("EVENTS.EVENTS.TABLE.TITLE")}{t("EVENTS.EVENTS.TABLE.PRESENTERS")}
    onChangeAllSelected(e)} - className="select-all-cbox" + checked={event.selected} + onChange={(e) => onChangeSelected(e, isEvent(event) ? event.id : "")} /> - - {t("EVENTS.EVENTS.TABLE.TITLE")}{t("EVENTS.EVENTS.TABLE.PRESENTERS")}
    - onChangeSelected(e, isEvent(event) ? event.id : "")} - /> - {isEvent(event) && event.title} - {/* Repeat for each presenter*/} + {isEvent(event) && event.title} + {/* Repeat for each presenter*/} {/* @ts-expect-error TS(7006): Parameter 'presenter' implicitly has an 'any' type... Remove this comment to see the full error message */} - {event.presenters.map((presenter, key) => ( - - {presenter} - - ))} -
    -
    + {event.presenters.map((presenter, key) => ( + + {presenter} + + ))} + +
    +
    -
    - - -
    +
    + + +
    -
    - +
    ); }; diff --git a/src/components/events/partials/modals/DeleteSeriesModal.tsx b/src/components/events/partials/modals/DeleteSeriesModal.tsx index 1aaa578666..352cfe8908 100644 --- a/src/components/events/partials/modals/DeleteSeriesModal.tsx +++ b/src/components/events/partials/modals/DeleteSeriesModal.tsx @@ -125,112 +125,100 @@ const DeleteSeriesModal = ({ return ( <> -
    -
    -
    -
    - -
    -
    -
    -

    {t("BULK_ACTIONS.DELETE_SERIES_WARNING_LINE1")}

    -

    {t("BULK_ACTIONS.DELETE_SERIES_WARNING_LINE2")}

    -
    +
    +
    +
    +

    {t("BULK_ACTIONS.DELETE_SERIES_WARNING_LINE1")}

    +

    {t("BULK_ACTIONS.DELETE_SERIES_WARNING_LINE2")}

    +
    - {/* Only show if series not allowed to be deleted */} - {!isAllowed() && ( -
    -

    {t("BULK_ACTIONS.DELETE.SERIES.CANNOT_DELETE")}

    -
    - )} - -
    -
    -
    {t("EVENTS.SERIES.TABLE.CAPTION")}
    -
    - - - - + + ))} + +
    + {/* Only show if series not allowed to be deleted */} + {!isAllowed() && ( +
    +

    {t("BULK_ACTIONS.DELETE.SERIES.CANNOT_DELETE")}

    +
    + )} + +
    +
    +
    {t("EVENTS.SERIES.TABLE.CAPTION")}
    +
    + + + + + + + + + + + {/* Repeat for each marked series */} + {selectedSeries.map((series, key) => ( + + - - - - - - {/* Repeat for each marked series */} - {selectedSeries.map((series, key) => ( - - - - + + - {/* Only show check if row has events, else empty cell*/} - - - ))} - -
    + onChangeAllSelected(e)} + className="select-all-cbox" + /> + {t("EVENTS.SERIES.TABLE.TITLE")}{t("EVENTS.SERIES.TABLE.ORGANIZERS")}{t("EVENTS.SERIES.TABLE.HAS_EVENTS")}
    onChangeAllSelected(e)} - className="select-all-cbox" + name="selection" + checked={series.selected} + onChange={(e) => onChangeSelected(e, isSeries(series) ?series.id : "")} + className="child-cbox" /> - - {t("EVENTS.SERIES.TABLE.TITLE")}{t("EVENTS.SERIES.TABLE.ORGANIZERS")}{t("EVENTS.SERIES.TABLE.HAS_EVENTS")}
    - onChangeSelected(e, isSeries(series) ?series.id : "")} - className="child-cbox" - /> - {isSeries(series) && series.title} - {/*Repeat for each creator*/} + {isSeries(series) && series.title} + {/*Repeat for each creator*/} {/* @ts-expect-error TS(7006): Parameter 'organizer' implicitly has an 'any' type */} - {series.organizers.map((organizer, key) => ( - - {organizer} - - ))} - - {series.hasEvents && } -
    -
    + {series.organizers.map((organizer, key) => ( + + {organizer} + + ))} + + {/* Only show check if row has events, else empty cell*/} +
    + {series.hasEvents && } +
    - -
    - - -
    -
    +
    + +
    + + +
    ); }; diff --git a/src/components/events/partials/modals/EditMetadataEventsModal.tsx b/src/components/events/partials/modals/EditMetadataEventsModal.tsx index a0c6d7a2cd..838ed7cf48 100644 --- a/src/components/events/partials/modals/EditMetadataEventsModal.tsx +++ b/src/components/events/partials/modals/EditMetadataEventsModal.tsx @@ -17,8 +17,6 @@ import { updateBulkMetadata, } from "../../../../slices/eventSlice"; import { unwrapResult } from "@reduxjs/toolkit"; -import { useHotkeys } from "react-hotkeys-hook"; -import { availableHotkeys } from "../../../../configs/hotkeysConfig"; import { isEvent } from "../../../../slices/tableSlice"; /** @@ -50,13 +48,6 @@ const EditMetadataEventsModal = ({ const user = useAppSelector(state => getUserInformation(state)); - useHotkeys( - availableHotkeys.general.CLOSE_MODAL.sequence, - () => close(), - { description: t(availableHotkeys.general.CLOSE_MODAL.description) ?? undefined }, - [close], - ); - useEffect(() => { async function fetchData() { setLoading(true); @@ -148,189 +139,181 @@ const EditMetadataEventsModal = ({ return ( <> -
    -
    -
    -
    - - {/* Loading spinner */} - {loading && ( -
    -
    -
    - -
    + {/* Loading spinner */} + {loading && ( +
    +
    +
    +
    - )} +
    + )} - {/* Fatal error view */} - {!!fatalError && ( -
    -
    -
    -
    -

    - {t("BULK_ACTIONS.EDIT_EVENTS_METADATA.FATAL_ERROR", { - fatalError: fatalError, - })} -

    -
    + {/* Fatal error view */} + {!!fatalError && ( +
    +
    +
    +
    +

    + {t("BULK_ACTIONS.EDIT_EVENTS_METADATA.FATAL_ERROR", { + fatalError: fatalError, + })} +

    - )} +
    + )} - {/* todo: Request Errors View and Update Errors View (not quite sure what this is used for) */} + {/* todo: Request Errors View and Update Errors View (not quite sure what this is used for) */} - {!loading && fatalError === undefined && ( - handleSubmit(values)} - > - {(formik) => ( - <> -
    -
    -
    -
    + {!loading && fatalError === undefined && ( + handleSubmit(values)} + > + {(formik) => ( + <> +
    +
    +
    +
    + + {t( + "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.DESCRIPTION" + )} + +
    +
    +
    {t( - "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.DESCRIPTION" + "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.CAPTION" )} -
    -
    -
    - - {t( - "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.CAPTION" - )} - -
    -
    - - - - - - - - - {metadataFields.mergedMetadata.map( - (metadata, key) => - !metadata.readOnly && ( - - - - + + + + ) + )} + +
    - - {t( - "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.FIELDS" - )} - - {t( - "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.VALUES" - )} -
    - - onChangeSelected(e, metadata.id) - } - className="child-cbox" - /> - - {t(metadata.label)} - {metadata.required && ( - * - )} - - {/* Render single value or multi value input */} - {metadata.type === "mixed_text" && - !!metadata.collection && - metadata.collection.length !== 0 ? ( - - ) : ( - + +
    + + + + + + + + + {metadataFields.mergedMetadata.map( + (metadata, key) => + !metadata.readOnly && ( + + - ) - )} - -
    + + {t( + "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.FIELDS" + )} + + {t( + "BULK_ACTIONS.EDIT_EVENTS_METADATA.EDIT.TABLE.VALUES" + )} +
    + -
    -
    + disabled={ + (!metadata.differentValues && + !metadata.selected) || + (metadata.required && + !metadata.selected) + } + onChange={(e) => + onChangeSelected(e, metadata.id) + } + className="child-cbox" + /> +
    + {t(metadata.label)} + {metadata.required && ( + * + )} + + {/* Render single value or multi value input */} + {metadata.type === "mixed_text" && + !!metadata.collection && + metadata.collection.length !== 0 ? ( + + ) : ( + + )} +
    +
    - {/* Buttons for cancel and submit */} -
    - - -
    + inactive: !( + formik.dirty && + formik.isValid && + hasAccess( + "ROLE_UI_EVENTS_DETAILS_METADATA_EDIT", + user + ) + ), + })} + > + {t("WIZARD.UPDATE")} + + + -
    - - )} - - )} -
    +
    + + )} + + )} ); }; diff --git a/src/components/events/partials/modals/EditScheduledEventsModal.tsx b/src/components/events/partials/modals/EditScheduledEventsModal.tsx index d64dd069aa..598896cc42 100644 --- a/src/components/events/partials/modals/EditScheduledEventsModal.tsx +++ b/src/components/events/partials/modals/EditScheduledEventsModal.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useState } from "react"; import { Formik } from "formik"; -import { useTranslation } from "react-i18next"; import { initialFormValuesEditScheduledEvents } from "../../../../configs/modalConfig"; import WizardStepper from "../../../shared/wizard/WizardStepper"; import EditScheduledEventsGeneralPage from "../ModalTabsAndPages/EditScheduledEventsGeneralPage"; @@ -21,8 +20,6 @@ import { Conflict, } from "../../../../slices/eventSlice"; import { fetchRecordings } from "../../../../slices/recordingSlice"; -import { useHotkeys } from "react-hotkeys-hook"; -import { availableHotkeys } from "../../../../configs/hotkeysConfig"; import { Event } from "../../../../slices/eventSlice"; /** @@ -33,7 +30,6 @@ const EditScheduledEventsModal = ({ }: { close: () => void }) => { - const { t } = useTranslation(); const dispatch = useAppDispatch(); const inputDevices = useAppSelector(state => getRecordings(state)); @@ -55,13 +51,6 @@ const EditScheduledEventsModal = ({ const user = useAppSelector(state => getUserInformation(state)); - useHotkeys( - availableHotkeys.general.CLOSE_MODAL.sequence, - () => close(), - { description: t(availableHotkeys.general.CLOSE_MODAL.description) ?? undefined }, - [close], - ); - useEffect(() => { // Load recordings that can be used for input dispatch(fetchRecordings("inputs")); @@ -125,67 +114,59 @@ const EditScheduledEventsModal = ({ return ( <> -
    -
    -
    -
    - - {/* Initialize overall form */} - validateFormik(values)} - onSubmit={(values) => handleSubmit(values)} - > - {/* Render wizard pages depending on current value of page variable */} - {(formik) => { - // eslint-disable-next-line react-hooks/rules-of-hooks - useEffect(() => { - formik.validateForm().then(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [page]); + {/* Initialize overall form */} + validateFormik(values)} + onSubmit={(values) => handleSubmit(values)} + > + {/* Render wizard pages depending on current value of page variable */} + {(formik) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + useEffect(() => { + formik.validateForm().then(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [page]); - return ( - <> - {/* Stepper that shows each step of wizard as header */} - -
    - {page === 0 && ( - - )} - {page === 1 && ( - - )} - {page === 2 && ( - - )} -
    - - ); - }} -
    -
    + return ( + <> + {/* Stepper that shows each step of wizard as header */} + +
    + {page === 0 && ( + + )} + {page === 1 && ( + + )} + {page === 2 && ( + + )} +
    + + ); + }} + ); }; diff --git a/src/components/events/partials/modals/EmbeddingCodeModal.tsx b/src/components/events/partials/modals/EmbeddingCodeModal.tsx index 271d96fe65..ed48d31557 100644 --- a/src/components/events/partials/modals/EmbeddingCodeModal.tsx +++ b/src/components/events/partials/modals/EmbeddingCodeModal.tsx @@ -1,8 +1,6 @@ import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { getSourceURL } from "../../../../utils/embeddedCodeUtils"; -import { useHotkeys } from "react-hotkeys-hook"; -import { availableHotkeys } from "../../../../configs/hotkeysConfig"; /** * This component renders the embedding code modal @@ -21,13 +19,6 @@ const EmbeddingCodeModal = ({ const [currentSize, setCurrentSize] = useState("0x0"); const [showCopySuccess, setCopySuccess] = useState(false); - useHotkeys( - availableHotkeys.general.CLOSE_MODAL.sequence, - () => close(), - { description: t(availableHotkeys.general.CLOSE_MODAL.description) ?? undefined }, - [close], - ); - useEffect(() => { const fetchData = async () => { // get source url @@ -38,10 +29,6 @@ const EmbeddingCodeModal = ({ fetchData(); }, []); - const handleClose = () => { - close(); - }; - const copy = () => { let copyText = document.getElementById("social_embed-textarea") as HTMLTextAreaElement; if (copyText) { @@ -92,92 +79,81 @@ const EmbeddingCodeModal = ({ return ( <> -
    -
    -
    -
    - - {/* embed size buttons */} -
    - - - - + {/* embed size buttons */} +
    + + + + + +
    + + + {eventId} + + + {/* text area containing current iFrame code to copy*/} +
    +