diff --git a/src/components/events/partials/EventsDateCell.tsx b/src/components/events/partials/EventsDateCell.tsx index d2bd5846a6..94a23a4704 100644 --- a/src/components/events/partials/EventsDateCell.tsx +++ b/src/components/events/partials/EventsDateCell.tsx @@ -1,6 +1,3 @@ -import { useTranslation } from "react-i18next"; -import { editFilterValue } from "../../../slices/tableFilterSlice"; -import React from "react"; import { loadEventsIntoTable } from "../../../thunks/tableThunks"; import { fetchEvents } from "../../../slices/eventSlice"; import { Event } from "../../../slices/eventSlice"; diff --git a/src/components/events/partials/EventsLocationCell.tsx b/src/components/events/partials/EventsLocationCell.tsx index 4a3b85f060..edbf6244c3 100644 --- a/src/components/events/partials/EventsLocationCell.tsx +++ b/src/components/events/partials/EventsLocationCell.tsx @@ -1,10 +1,7 @@ -import { getFilters } from "../../../selectors/tableFilterSelectors"; -import { editFilterValue } from "../../../slices/tableFilterSlice"; import { loadEventsIntoTable } from "../../../thunks/tableThunks"; -import { useAppDispatch, useAppSelector } from "../../../store"; import { fetchEvents } from "../../../slices/eventSlice"; import { Event } from "../../../slices/eventSlice"; -import ButtonLikeAnchor from "../../shared/ButtonLikeAnchor"; +import FilterCell from "../../shared/FilterCell"; /** * This component renders the location cells of events in the table view @@ -14,29 +11,18 @@ const EventsLocationCell = ({ }: { row: Event }) => { - const dispatch = useAppDispatch(); - - const filterMap = useAppSelector(state => getFilters(state, "events")); - - // Filter with value of current cell - const addFilter = (location: string) => { - const filter = filterMap.find(({ name }) => name === "location"); - if (filter) { - dispatch(editFilterValue({ filterName: filter.name, value: location, resource: "events" })); - dispatch(fetchEvents()); - dispatch(loadEventsIntoTable()); - } - }; - return ( - // Link template for location of event - addFilter(row.location)} - className={"crosslink"} - tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.LOCATION"} - > - {row.location} - + ); }; diff --git a/src/components/events/partials/EventsPresentersCell.tsx b/src/components/events/partials/EventsPresentersCell.tsx index e1ed2668ce..56b42c42e3 100644 --- a/src/components/events/partials/EventsPresentersCell.tsx +++ b/src/components/events/partials/EventsPresentersCell.tsx @@ -1,7 +1,7 @@ import { loadEventsIntoTable } from "../../../thunks/tableThunks"; import { fetchEvents } from "../../../slices/eventSlice"; import { Event } from "../../../slices/eventSlice"; -import MultiValueCell from "../../shared/MultiValueCell"; +import FilterCell from "../../shared/FilterCell"; /** * This component renders the presenters cells of events in the table view @@ -12,13 +12,16 @@ const EventsPresentersCell = ({ row: Event }) => { return ( - ({ + filterValue: presenter, + children: presenter, + cellTooltipText: "EVENTS.EVENTS.TABLE.TOOLTIP.PRESENTER", + }))} fetchResource={fetchEvents} loadResourceIntoTable={loadEventsIntoTable} - tooltipText="EVENTS.EVENTS.TABLE.TOOLTIP.PRESENTER" /> ); }; diff --git a/src/components/events/partials/EventsSeriesCell.tsx b/src/components/events/partials/EventsSeriesCell.tsx index dc9a3f47d2..97054182b5 100644 --- a/src/components/events/partials/EventsSeriesCell.tsx +++ b/src/components/events/partials/EventsSeriesCell.tsx @@ -1,10 +1,7 @@ -import { getFilters } from "../../../selectors/tableFilterSelectors"; -import { editFilterValue } from "../../../slices/tableFilterSlice"; import { loadEventsIntoTable } from "../../../thunks/tableThunks"; -import { useAppDispatch, useAppSelector } from "../../../store"; import { fetchEvents } from "../../../slices/eventSlice"; import { Event } from "../../../slices/eventSlice"; -import ButtonLikeAnchor from "../../shared/ButtonLikeAnchor"; +import FilterCell from "../../shared/FilterCell"; /** * This component renders the series cells of events in the table view @@ -14,33 +11,19 @@ const EventsSeriesCell = ({ }: { row: Event }) => { - const dispatch = useAppDispatch(); - - const filterMap = useAppSelector(state => getFilters(state, "events")); - - // Filter with value of current cell - const addFilter = async (seriesId: string) => { - const filter = filterMap.find(({ name }) => name === "series"); - if (filter) { - dispatch(editFilterValue({ filterName: filter.name, value: seriesId, resource: "events" })); - await dispatch(fetchEvents()); - dispatch(loadEventsIntoTable()); - } - }; - return ( row.series ? ( - // Link template for series of event - row.series - ? addFilter(row.series.id) - : console.error("Tried to sort by a series, but the series did not exist.") - } - className={"crosslink"} - tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.SERIES"} - > - {row.series.title} - + ) : <> ); diff --git a/src/components/events/partials/EventsTechnicalDateCell.tsx b/src/components/events/partials/EventsTechnicalDateCell.tsx deleted file mode 100644 index d61878517d..0000000000 --- a/src/components/events/partials/EventsTechnicalDateCell.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { getFilters } from "../../../selectors/tableFilterSelectors"; -import { editFilterValue } from "../../../slices/tableFilterSlice"; -import { loadEventsIntoTable } from "../../../thunks/tableThunks"; -import { useAppDispatch, useAppSelector } from "../../../store"; -import { fetchEvents } from "../../../slices/eventSlice"; -import { renderValidDate } from "../../../utils/dateUtils"; -import { Event } from "../../../slices/eventSlice"; -import ButtonLikeAnchor from "../../shared/ButtonLikeAnchor"; - -/** - * This component renders the technical date cells of events in the table view - */ -const EventsTechnicalDateCell = ({ - row, -}: { - row: Event -}) => { - const { t } = useTranslation(); - const dispatch = useAppDispatch(); - - const filterMap = useAppSelector(state => getFilters(state, "events")); - - // Filter with value of current cell - const addFilter = async (date: string) => { - const filter = filterMap.find(({ name }) => name === "technicalStart"); - if (filter) { - dispatch(editFilterValue({ filterName: filter.name, value: date + "/" + date, resource: "events" })); - await dispatch(fetchEvents()); - dispatch(loadEventsIntoTable()); - } - }; - - return ( - // Link template for technical date of event - addFilter(row.date)} - className={"crosslink"} - tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.START"} - > - {t("dateFormats.date.short", { date: renderValidDate(row.technical_start) })} - - ); -}; - -export default EventsTechnicalDateCell; diff --git a/src/components/events/partials/SeriesTitleCell.tsx b/src/components/events/partials/SeriesTitleCell.tsx index 8f5c8b0dff..9d2f2a1a88 100644 --- a/src/components/events/partials/SeriesTitleCell.tsx +++ b/src/components/events/partials/SeriesTitleCell.tsx @@ -2,7 +2,7 @@ import { setSpecificEventFilter } from "../../../slices/tableFilterSlice"; import { useNavigate } from "react-router"; import { useAppDispatch } from "../../../store"; import { Series } from "../../../slices/seriesSlice"; -import BaseButton from "../../shared/BaseButton"; +import RedirectCell from "../../shared/RedirectCell"; /** * This component renders the title cells of series in the table view @@ -12,23 +12,15 @@ const SeriesTitleCell = ({ }: { row: Series }) => { - const dispatch = useAppDispatch(); - const navigate = useNavigate(); - - const redirectToEvents = async (seriesId: string) => { - // set the series filter value of events to series title - await dispatch(setSpecificEventFilter({ filter: "series", filterValue: seriesId })); - navigate("/events/events"); - }; - return ( - redirectToEvents(row.id)} > {row.title} - + ); }; diff --git a/src/components/recordings/partials/RecordingsNameCell.tsx b/src/components/recordings/partials/RecordingsNameCell.tsx index 1a0f2e5972..713dd582e4 100644 --- a/src/components/recordings/partials/RecordingsNameCell.tsx +++ b/src/components/recordings/partials/RecordingsNameCell.tsx @@ -1,8 +1,5 @@ -import { useNavigate } from "react-router"; -import { setSpecificEventFilter } from "../../../slices/tableFilterSlice"; -import { useAppDispatch } from "../../../store"; import { Recording } from "../../../slices/recordingSlice"; -import BaseButton from "../../shared/BaseButton"; +import RedirectCell from "../../shared/RedirectCell"; /** * This component renders the name cells of recordings in the table view @@ -12,23 +9,15 @@ const RecordingsNameCell = ({ }: { row: Recording }) => { - const dispatch = useAppDispatch(); - const navigate = useNavigate(); - - const redirectToEvents = async (locationName: string) => { - // set the location filter value of events to location name - await dispatch(setSpecificEventFilter({ filter: "location", filterValue: locationName })); - navigate("/events/events"); - }; - return ( - redirectToEvents(row.name)} > {row.name} - + ); }; diff --git a/src/components/shared/FilterCell.tsx b/src/components/shared/FilterCell.tsx new file mode 100644 index 0000000000..3ee7a6fd98 --- /dev/null +++ b/src/components/shared/FilterCell.tsx @@ -0,0 +1,61 @@ +import { getFilters } from "../../selectors/tableFilterSelectors"; +import { editFilterValue } from "../../slices/tableFilterSlice"; +import { AppThunk, useAppDispatch, useAppSelector } from "../../store"; +import { Resource } from "../../slices/tableSlice"; +import { AsyncThunk } from "@reduxjs/toolkit"; +import { ParseKeys } from "i18next"; +import { ReactNode } from "react"; +import BaseButton from "./BaseButton"; +import ButtonLikeAnchor from "./ButtonLikeAnchor"; + +/** + * This component renders a table cell with one or more clickable items + * where clicking the items will set a filter + */ +const FilterCell = ({ + resource, + filterName, + filterItems, + fetchResource, + loadResourceIntoTable, +}: { + resource: Resource + filterName: string + filterItems: { + filterValue: string + children: ReactNode + cellTooltipText?: ParseKeys + }[] + fetchResource: AsyncThunk + loadResourceIntoTable: () => AppThunk, +}) => { + const dispatch = useAppDispatch(); + + const filterMap = useAppSelector(state => getFilters(state, resource)); + + // Filter with value of current cell + const addFilter = async (filterValue: string) => { + const filter = filterMap.find(({ name }) => name === filterName); + if (filter) { + dispatch(editFilterValue({ filterName: filter.name, value: filterValue, resource })); + await dispatch(fetchResource()); + dispatch(loadResourceIntoTable()); + } + }; + + return ( + // Link template for location of event + filterItems.map((item, key) => ( + addFilter(item.filterValue)} + className={"crosslink"} + tooltipText={item.cellTooltipText} + > + {item.children} + + )) + ); +}; + +export default FilterCell; diff --git a/src/components/shared/RedirectCell.tsx b/src/components/shared/RedirectCell.tsx new file mode 100644 index 0000000000..3e217b2f7b --- /dev/null +++ b/src/components/shared/RedirectCell.tsx @@ -0,0 +1,44 @@ +import { useNavigate } from "react-router"; +import { setSpecificEventFilter } from "../../slices/tableFilterSlice"; +import { useAppDispatch } from "../../store"; +import ButtonLikeAnchor from "./ButtonLikeAnchor"; +import { ParseKeys } from "i18next"; +import { ReactNode } from "react"; + +/** + * This component renders the name cells of recordings in the table view + */ +const RedirectCell = ({ + path, + filterName, + filterValue, + tooltipText, + children, +}: { + path: string + filterName: string + filterValue: string + tooltipText?: ParseKeys + children: ReactNode +}) => { + const dispatch = useAppDispatch(); + const navigate = useNavigate(); + + const redirectToResource = async (filterValue: string) => { + // Set filter before redirecting + await dispatch(setSpecificEventFilter({ filter: filterName, filterValue })); + navigate(path); + }; + + return ( + redirectToResource(filterValue)} + > + {children} + + ); +}; + +export default RedirectCell; diff --git a/src/configs/tableConfigs/eventsTableMap.ts b/src/configs/tableConfigs/eventsTableMap.ts index 26a709ce4d..3a493c1ba8 100644 --- a/src/configs/tableConfigs/eventsTableMap.ts +++ b/src/configs/tableConfigs/eventsTableMap.ts @@ -3,7 +3,6 @@ import EventsDateCell from "../../components/events/partials/EventsDateCell"; import EventsPresentersCell from "../../components/events/partials/EventsPresentersCell"; import EventsSeriesCell from "../../components/events/partials/EventsSeriesCell"; import EventsStatusCell from "../../components/events/partials/EventsStatusCell"; -import EventsTechnicalDateCell from "../../components/events/partials/EventsTechnicalDateCell"; import PublishedCell from "../../components/events/partials/PublishedCell"; import EventsLocationCell from "../../components/events/partials/EventsLocationCell"; import EventsEndCell from "../../components/events/partials/EventsEndCell"; @@ -23,7 +22,6 @@ export const eventsTemplateMap = { EventsPresentersCell: EventsPresentersCell, EventsSeriesCell: EventsSeriesCell, EventsStatusCell: EventsStatusCell, - EventsTechnicalDateCell: EventsTechnicalDateCell, PublishedCell: PublishedCell, EventsNotesCell: EventsNotesCell, };