From ae4fbd6348d14b3585993059a7bdd2bbb8055518 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 18 Dec 2024 15:13:54 +0100 Subject: [PATCH 01/11] Fix notification display in event metadata tab Notifications were not being rendered in the metadata tab of the event details, especially the "Active Workflow"-notification. This patch fixes that. This patch also fixes: - The "Active Workflow"-notification being rendered multiple times. - The "Active Workflow"-notification being rendered even when there is no active workflow anymore. --- src/components/configuration/Themes.tsx | 2 +- .../partials/wizard/GeneralPage.tsx | 2 +- src/components/events/Events.tsx | 2 +- src/components/events/Series.tsx | 2 +- .../ModalTabsAndPages/DetailsMetadataTab.tsx | 2 +- .../EventDetailsCommentsTab.tsx | 2 +- .../EventDetailsPublicationTab.tsx | 2 +- .../events/partials/modals/EventDetails.tsx | 31 ++++++++++++++++++- src/components/recordings/Recordings.tsx | 2 +- src/components/shared/Notifications.tsx | 8 ++++- .../modals/ResourceDetailsAccessPolicyTab.tsx | 3 +- src/components/systems/Jobs.tsx | 2 +- src/components/systems/Servers.tsx | 2 +- src/components/systems/Services.tsx | 2 +- src/components/users/Acls.tsx | 4 +-- src/components/users/Groups.tsx | 4 +-- src/components/users/Users.tsx | 4 +-- .../partials/wizard/NewAclSummaryPage.tsx | 2 +- .../partials/wizard/NewGroupSummaryPage.tsx | 2 +- .../partials/wizard/NewUserGeneralTab.tsx | 2 +- src/slices/eventDetailsSlice.ts | 12 ------- 21 files changed, 59 insertions(+), 35 deletions(-) diff --git a/src/components/configuration/Themes.tsx b/src/components/configuration/Themes.tsx index fa4fab200c..1af3268b7b 100644 --- a/src/components/configuration/Themes.tsx +++ b/src/components/configuration/Themes.tsx @@ -114,7 +114,7 @@ const Themes = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/configuration/partials/wizard/GeneralPage.tsx b/src/components/configuration/partials/wizard/GeneralPage.tsx index 2e0ea8cb35..7b148b4ae9 100644 --- a/src/components/configuration/partials/wizard/GeneralPage.tsx +++ b/src/components/configuration/partials/wizard/GeneralPage.tsx @@ -35,7 +35,7 @@ const GeneralPage = ({
- + diff --git a/src/components/events/Events.tsx b/src/components/events/Events.tsx index 0e1337a4f6..e9f57c7a73 100644 --- a/src/components/events/Events.tsx +++ b/src/components/events/Events.tsx @@ -251,7 +251,7 @@ const Events = () => { {/* Include notifications component */} - +
diff --git a/src/components/events/Series.tsx b/src/components/events/Series.tsx index 4dcce7f070..a5236e0098 100644 --- a/src/components/events/Series.tsx +++ b/src/components/events/Series.tsx @@ -200,7 +200,7 @@ const Series = () => { {/* Include notifications component */} - +
diff --git a/src/components/events/partials/ModalTabsAndPages/DetailsMetadataTab.tsx b/src/components/events/partials/ModalTabsAndPages/DetailsMetadataTab.tsx index 179f2abd10..4d4e1f189f 100644 --- a/src/components/events/partials/ModalTabsAndPages/DetailsMetadataTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/DetailsMetadataTab.tsx @@ -79,7 +79,7 @@ const DetailsMetadataTab = ({ <>
- +
{t(header)}
diff --git a/src/components/events/partials/ModalTabsAndPages/EventDetailsCommentsTab.tsx b/src/components/events/partials/ModalTabsAndPages/EventDetailsCommentsTab.tsx index d8c8ab4977..c23849709c 100644 --- a/src/components/events/partials/ModalTabsAndPages/EventDetailsCommentsTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/EventDetailsCommentsTab.tsx @@ -111,7 +111,7 @@ const EventDetailsCommentsTab = ({ return (
- +
{t(header)}
diff --git a/src/components/events/partials/ModalTabsAndPages/EventDetailsPublicationTab.tsx b/src/components/events/partials/ModalTabsAndPages/EventDetailsPublicationTab.tsx index ca9a0b97f6..b266b60ee4 100644 --- a/src/components/events/partials/ModalTabsAndPages/EventDetailsPublicationTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/EventDetailsPublicationTab.tsx @@ -30,7 +30,7 @@ const EventDetailsPublicationTab = ({ <>
- +
{t("EVENTS.EVENTS.DETAILS.PUBLICATIONS.CAPTION")}
diff --git a/src/components/events/partials/modals/EventDetails.tsx b/src/components/events/partials/modals/EventDetails.tsx index bb11401a7d..12e72eba70 100644 --- a/src/components/events/partials/modals/EventDetails.tsx +++ b/src/components/events/partials/modals/EventDetails.tsx @@ -41,9 +41,12 @@ import { fetchEventStatistics, openModalTab, fetchEventDetailsTobira, + fetchHasActiveTransactions, } from "../../../../slices/eventDetailsSlice"; -import { removeNotificationWizardForm } from "../../../../slices/notificationSlice"; +import { addNotification, removeNotificationByKey, removeNotificationWizardForm } from "../../../../slices/notificationSlice"; import DetailsTobiraTab from "../ModalTabsAndPages/DetailsTobiraTab"; +import { NOTIFICATION_CONTEXT } from "../../../../configs/modalConfig"; +import { unwrapResult } from "@reduxjs/toolkit"; export enum EventDetailsPage { Metadata, @@ -84,6 +87,32 @@ const EventDetails = ({ dispatch(fetchSchedulingInfo(eventId)).then(); dispatch(fetchEventStatistics(eventId)).then(); dispatch(fetchAssetUploadOptions()).then(); + + dispatch(fetchHasActiveTransactions(eventId)).then((fetchTransactionResult) => { + const result = unwrapResult(fetchTransactionResult) + if (result.active !== undefined && result.active) { + dispatch( + addNotification({ + type: "warning", + key: "ACTIVE_TRANSACTION", + duration: -1, + parameter: undefined, + context: NOTIFICATION_CONTEXT, + noDuplicates: true + }) + ) + } + if (result.active !== undefined && !result.active) { + dispatch( + removeNotificationByKey({ + key: "ACTIVE_TRANSACTION", + context: NOTIFICATION_CONTEXT + }) + ) + } + }); + + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/src/components/recordings/Recordings.tsx b/src/components/recordings/Recordings.tsx index b030f0dce9..f7faab4751 100644 --- a/src/components/recordings/Recordings.tsx +++ b/src/components/recordings/Recordings.tsx @@ -81,7 +81,7 @@ const Recordings = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/shared/Notifications.tsx b/src/components/shared/Notifications.tsx index 106ae59de6..88be2ced00 100644 --- a/src/components/shared/Notifications.tsx +++ b/src/components/shared/Notifications.tsx @@ -13,10 +13,16 @@ import { import { useAppDispatch, useAppSelector } from "../../store"; import { OurNotification, setHidden } from "../../slices/notificationSlice"; +type Context = "not_corner" | "tobira" | "above_table" | "other" + /** * This component renders notifications about occurred errors, warnings and info */ -const Notifications : React.FC<{ context?: string }> = ({ context }) => { +const Notifications = ({ + context, +}: { + context: Context, +}) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); diff --git a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx index 3583664285..17becceab8 100644 --- a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx +++ b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx @@ -107,7 +107,8 @@ const ResourceDetailsAccessPolicyTab = ({ key: "ACTIVE_TRANSACTION", duration: -1, parameter: undefined, - context: NOTIFICATION_CONTEXT + context: NOTIFICATION_CONTEXT, + noDuplicates: true, })); } } diff --git a/src/components/systems/Jobs.tsx b/src/components/systems/Jobs.tsx index ea81b0afa0..28b1dde1f4 100644 --- a/src/components/systems/Jobs.tsx +++ b/src/components/systems/Jobs.tsx @@ -131,7 +131,7 @@ const Jobs = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/systems/Servers.tsx b/src/components/systems/Servers.tsx index dea50ec9a2..98662a9832 100644 --- a/src/components/systems/Servers.tsx +++ b/src/components/systems/Servers.tsx @@ -131,7 +131,7 @@ const Servers = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/systems/Services.tsx b/src/components/systems/Services.tsx index 672561ef44..b7c145c4a5 100644 --- a/src/components/systems/Services.tsx +++ b/src/components/systems/Services.tsx @@ -130,7 +130,7 @@ const Services = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/users/Acls.tsx b/src/components/users/Acls.tsx index e018947ae0..c20be8159d 100644 --- a/src/components/users/Acls.tsx +++ b/src/components/users/Acls.tsx @@ -145,7 +145,7 @@ const Acls: React.FC = () => { )} - + {/* Add acl button */}
{hasAccess("ROLE_UI_ACLS_CREATE", user) && ( @@ -159,7 +159,7 @@ const Acls: React.FC = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/users/Groups.tsx b/src/components/users/Groups.tsx index b6e267309c..22e2fb0d5c 100644 --- a/src/components/users/Groups.tsx +++ b/src/components/users/Groups.tsx @@ -145,7 +145,7 @@ const Groups = () => { )} - + {/* Add group button */}
{hasAccess("ROLE_UI_GROUPS_CREATE", user) && ( @@ -159,7 +159,7 @@ const Groups = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/users/Users.tsx b/src/components/users/Users.tsx index f3c1f8ff1e..20099c0361 100644 --- a/src/components/users/Users.tsx +++ b/src/components/users/Users.tsx @@ -145,7 +145,7 @@ const Users: React.FC = () => { )} - + {/* Add user button */}
{hasAccess("ROLE_UI_USERS_CREATE", user) && ( @@ -159,7 +159,7 @@ const Users: React.FC = () => { {/* Include notifications component */} - +
{/* Include filters component */} diff --git a/src/components/users/partials/wizard/NewAclSummaryPage.tsx b/src/components/users/partials/wizard/NewAclSummaryPage.tsx index 48d7b29be0..cf09f7ed9e 100644 --- a/src/components/users/partials/wizard/NewAclSummaryPage.tsx +++ b/src/components/users/partials/wizard/NewAclSummaryPage.tsx @@ -24,7 +24,7 @@ const NewAclSummaryPage = ({
- +
{t("")}
diff --git a/src/components/users/partials/wizard/NewGroupSummaryPage.tsx b/src/components/users/partials/wizard/NewGroupSummaryPage.tsx index ff03c7b84d..43a6b6d498 100644 --- a/src/components/users/partials/wizard/NewGroupSummaryPage.tsx +++ b/src/components/users/partials/wizard/NewGroupSummaryPage.tsx @@ -31,7 +31,7 @@ const NewGroupSummaryPage = ({
- +
{t("USERS.GROUPS.DETAILS.FORM.SUMMARY")}
diff --git a/src/components/users/partials/wizard/NewUserGeneralTab.tsx b/src/components/users/partials/wizard/NewUserGeneralTab.tsx index 21ee9ae421..6af867a5bd 100644 --- a/src/components/users/partials/wizard/NewUserGeneralTab.tsx +++ b/src/components/users/partials/wizard/NewUserGeneralTab.tsx @@ -27,7 +27,7 @@ const NewUserGeneralTab = ({
- + {/* Fields for user information needed */}
)} - +
{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*/} +
    +