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,
};