Skip to content

Commit 68569f8

Browse files
authored
Merge pull request #1300 from Arnei/click-to-filter-in-series-table
Click-to-filter in series table
2 parents 6c9031e + 5d55d06 commit 68569f8

11 files changed

Lines changed: 205 additions & 110 deletions

File tree

src/components/events/partials/EventsDateCell.tsx

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import React from "react";
2-
import { useTranslation } from "react-i18next";
3-
import { editFilterValue } from "../../../slices/tableFilterSlice";
42
import { loadEventsIntoTable } from "../../../thunks/tableThunks";
5-
import { getFilters } from "../../../selectors/tableFilterSelectors";
6-
import { useAppDispatch, useAppSelector } from "../../../store";
73
import { fetchEvents } from "../../../slices/eventSlice";
8-
import { renderValidDate } from "../../../utils/dateUtils";
94
import { Event } from "../../../slices/eventSlice";
10-
import { IconButton } from "../../shared/IconButton";
5+
import DateTimeCell from "../../shared/DateTimeCell";
116

127
/**
138
* This component renders the start date cells of events in the table view
@@ -17,39 +12,15 @@ const EventsDateCell = ({
1712
}: {
1813
row: Event
1914
}) => {
20-
const { t } = useTranslation();
21-
const dispatch = useAppDispatch();
22-
23-
const filterMap = useAppSelector(state => getFilters(state, "events"));
24-
25-
// Filter with value of current cell
26-
const addFilter = async (date: string) => {
27-
let filter = filterMap.find(({ name }) => name === "startDate");
28-
if (!!filter) {
29-
let startDate = new Date(date);
30-
startDate.setHours(0);
31-
startDate.setMinutes(0);
32-
startDate.setSeconds(0);
33-
let endDate = new Date(date);
34-
endDate.setHours(23);
35-
endDate.setMinutes(59);
36-
endDate.setSeconds(59);
37-
38-
await dispatch(editFilterValue({filterName: filter.name, value: startDate.toISOString() + "/" + endDate.toISOString()}));
39-
await dispatch(fetchEvents());
40-
dispatch(loadEventsIntoTable());
41-
}
42-
};
43-
4415
return (
45-
// Link template for start date of event
46-
<IconButton
47-
callback={() => addFilter(row.date)}
48-
iconClassname={"crosslink"}
49-
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.START"}
50-
>
51-
{t("dateFormats.date.short", { date: renderValidDate(row.date) })}
52-
</IconButton>
16+
<DateTimeCell
17+
resource="events"
18+
date={row.date}
19+
filterName="startDate"
20+
fetchResource={fetchEvents}
21+
loadResourceIntoTable={loadEventsIntoTable}
22+
tooltipText="EVENTS.EVENTS.TABLE.TOOLTIP.START"
23+
/>
5324
);
5425
};
5526

src/components/events/partials/EventsPresentersCell.tsx

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import React from "react";
2-
import { getFilters } from "../../../selectors/tableFilterSelectors";
3-
import { editFilterValue } from "../../../slices/tableFilterSlice";
42
import { loadEventsIntoTable } from "../../../thunks/tableThunks";
5-
import { useAppDispatch, useAppSelector } from "../../../store";
63
import { fetchEvents } from "../../../slices/eventSlice";
74
import { Event } from "../../../slices/eventSlice";
8-
import { IconButton } from "../../shared/IconButton";
5+
import MultiValueCell from "../../shared/MultiValueCell";
96

107
/**
118
* This component renders the presenters cells of events in the table view
@@ -15,35 +12,15 @@ const EventsPresentersCell = ({
1512
}: {
1613
row: Event
1714
}) => {
18-
const dispatch = useAppDispatch();
19-
20-
const filterMap = useAppSelector(state => getFilters(state, "events"));
21-
22-
// Filter with value of current cell
23-
const addFilter = async (presenter: string) => {
24-
let filter = filterMap.find(
25-
({ name }) => name === "presentersBibliographic"
26-
);
27-
if (!!filter) {
28-
await dispatch(editFilterValue({filterName: filter.name, value: presenter}));
29-
await dispatch(fetchEvents());
30-
dispatch(loadEventsIntoTable());
31-
}
32-
};
33-
3415
return (
35-
// Link template for presenter of event
36-
// Repeat for each presenter
37-
row.presenters.map((presenter, key) => (
38-
<IconButton
39-
key={key}
40-
callback={() => addFilter(presenter)}
41-
iconClassname={"metadata-entry"}
42-
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.PRESENTER"}
43-
>
44-
{presenter}
45-
</IconButton>
46-
))
16+
<MultiValueCell
17+
resource="events"
18+
values={row.presenters}
19+
filterName="presentersBibliographic"
20+
fetchResource={fetchEvents}
21+
loadResourceIntoTable={loadEventsIntoTable}
22+
tooltipText="EVENTS.EVENTS.TABLE.TOOLTIP.PRESENTER"
23+
/>
4724
);
4825
};
4926

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from "react";
2-
import { Series } from "../../../slices/seriesSlice";
2+
import { fetchSeries, Series } from "../../../slices/seriesSlice";
3+
import { loadSeriesIntoTable } from "../../../thunks/tableThunks";
4+
import MultiValueCell from "../../shared/MultiValueCell";
35

46
/**
57
* This component renders the contributors cells of series in the table view
@@ -9,11 +11,16 @@ const SeriesContributorsCell = ({
911
}: {
1012
row: Series
1113
}) => {
12-
return row.contributors.map((contributor, key) => (
13-
<span key={key} className="metadata-entry">
14-
{contributor}
15-
</span>
16-
));
14+
return (
15+
<MultiValueCell
16+
resource="series"
17+
values={row.contributors}
18+
filterName="contributors"
19+
fetchResource={fetchSeries}
20+
loadResourceIntoTable={loadSeriesIntoTable}
21+
tooltipText="EVENTS.SERIES.TABLE.TOOLTIP.CONTRIBUTORS"
22+
/>
23+
);
1724
};
1825

1926
export default SeriesContributorsCell;

src/components/events/partials/SeriesCreatorsCell.tsx

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/components/events/partials/SeriesDateTimeCell.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from "react";
2-
import { useTranslation } from "react-i18next";
3-
import { renderValidDate } from "../../../utils/dateUtils";
4-
import { Series } from "../../../slices/seriesSlice";
2+
import { fetchSeries, Series } from "../../../slices/seriesSlice";
3+
import { loadSeriesIntoTable } from "../../../thunks/tableThunks";
4+
import DateTimeCell from "../../shared/DateTimeCell";
55

66
/**
77
* This component renders the creation date cells of series in the table view
@@ -11,15 +11,22 @@ const SeriesDateTimeCell = ({
1111
}: {
1212
row: Series
1313
}) => {
14-
const { t } = useTranslation();
15-
1614
return (
17-
// Link template for creation date of series
18-
<span>
19-
{t("dateFormats.date.short", {
20-
date: row.creation_date ? renderValidDate(row.creation_date) : "",
21-
})}
22-
</span>
15+
<>
16+
{row.creation_date !== undefined && (() => {
17+
const creationDate = row.creation_date;
18+
return (
19+
<DateTimeCell
20+
resource="series"
21+
date={creationDate}
22+
filterName="CreationDate"
23+
fetchResource={fetchSeries}
24+
loadResourceIntoTable={loadSeriesIntoTable}
25+
tooltipText="EVENTS.SERIES.TABLE.TOOLTIP.CREATION"
26+
/>
27+
);
28+
})()}
29+
</>
2330
);
2431
};
2532

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from "react";
2+
import { fetchSeries, Series } from "../../../slices/seriesSlice";
3+
import { loadSeriesIntoTable } from "../../../thunks/tableThunks";
4+
import MultiValueCell from "../../shared/MultiValueCell";
5+
6+
/**
7+
* This component renders the creators cells of series in the table view
8+
*/
9+
const SeriesOrganizersCell = ({
10+
row
11+
}: {
12+
row: Series
13+
}) => {
14+
return (
15+
<MultiValueCell
16+
resource="series"
17+
values={row.organizers}
18+
filterName="organizers"
19+
fetchResource={fetchSeries}
20+
loadResourceIntoTable={loadSeriesIntoTable}
21+
tooltipText="EVENTS.SERIES.TABLE.TOOLTIP.ORGANIZER"
22+
/>
23+
);
24+
};
25+
26+
export default SeriesOrganizersCell;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from "react";
2+
import { useTranslation } from "react-i18next";
3+
import { editFilterValue } from "../../slices/tableFilterSlice";
4+
import { getFilters } from "../../selectors/tableFilterSelectors";
5+
import { AppThunk, useAppDispatch, useAppSelector } from "../../store";
6+
import { renderValidDate } from "../../utils/dateUtils";
7+
import { IconButton } from "../shared/IconButton";
8+
import { ParseKeys } from "i18next";
9+
import { AsyncThunk } from "@reduxjs/toolkit";
10+
11+
/**
12+
* This component renders the start date cells of events in the table view
13+
*/
14+
const DateTimeCell = ({
15+
resource,
16+
date,
17+
filterName,
18+
fetchResource,
19+
loadResourceIntoTable,
20+
tooltipText,
21+
}: {
22+
resource: string
23+
date: string
24+
filterName: string
25+
fetchResource: AsyncThunk<any, void, any>
26+
loadResourceIntoTable: () => AppThunk
27+
tooltipText: ParseKeys
28+
}) => {
29+
const { t } = useTranslation();
30+
const dispatch = useAppDispatch();
31+
32+
const filterMap = useAppSelector(state => getFilters(state, resource));
33+
34+
// Filter with value of current cell
35+
const addFilter = async (date: string) => {
36+
let filter = filterMap.find(({ name }) => name === filterName);
37+
if (!!filter) {
38+
let startDate = new Date(date);
39+
startDate.setHours(0);
40+
startDate.setMinutes(0);
41+
startDate.setSeconds(0);
42+
let endDate = new Date(date);
43+
endDate.setHours(23);
44+
endDate.setMinutes(59);
45+
endDate.setSeconds(59);
46+
47+
await dispatch(editFilterValue({filterName: filter.name, value: startDate.toISOString() + "/" + endDate.toISOString()}));
48+
await dispatch(fetchResource());
49+
dispatch(loadResourceIntoTable());
50+
}
51+
};
52+
53+
return (
54+
// Link template for start date of event
55+
<IconButton
56+
callback={() => addFilter(date)}
57+
iconClassname={"crosslink"}
58+
tooltipText={tooltipText}
59+
>
60+
{t("dateFormats.date.short", { date: renderValidDate(date) })}
61+
</IconButton>
62+
);
63+
};
64+
65+
export default DateTimeCell;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from "react";
2+
import { getFilters } from "../../selectors/tableFilterSelectors";
3+
import { editFilterValue } from "../../slices/tableFilterSlice";
4+
import { AppThunk, useAppDispatch, useAppSelector } from "../../store";
5+
import { IconButton } from "../shared/IconButton";
6+
import { AsyncThunk } from "@reduxjs/toolkit";
7+
import { ParseKeys } from "i18next";
8+
9+
/**
10+
* This component renders the presenters cells of events in the table view
11+
*/
12+
const MultiValueCell = ({
13+
resource,
14+
values,
15+
filterName,
16+
fetchResource,
17+
loadResourceIntoTable,
18+
tooltipText,
19+
}: {
20+
resource: string
21+
values: string[]
22+
filterName: string
23+
fetchResource: AsyncThunk<any, void, any>
24+
loadResourceIntoTable: () => AppThunk
25+
tooltipText: ParseKeys,
26+
}) => {
27+
const dispatch = useAppDispatch();
28+
29+
const filterMap = useAppSelector(state => getFilters(state, resource));
30+
31+
// Filter with value of current cell
32+
const addFilter = async (presenter: string) => {
33+
let filter = filterMap.find(
34+
({ name }) => name === filterName
35+
);
36+
if (!!filter) {
37+
await dispatch(editFilterValue({filterName: filter.name, value: presenter}));
38+
await dispatch(fetchResource());
39+
dispatch(loadResourceIntoTable());
40+
}
41+
};
42+
43+
return (
44+
// Link template for each value
45+
values.map((value, key) => (
46+
<IconButton
47+
key={key}
48+
callback={() => addFilter(value)}
49+
iconClassname={"metadata-entry"}
50+
tooltipText={tooltipText}
51+
>
52+
{value}
53+
</IconButton>
54+
))
55+
);
56+
};
57+
58+
export default MultiValueCell;

src/configs/tableConfigs/seriesTableConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const seriesTableConfig: TableConfig = {
1919
sortable: true,
2020
},
2121
{
22-
template: "SeriesCreatorsCell",
22+
template: "SeriesOrganizersCell",
2323
name: "organizers",
2424
label: "EVENTS.SERIES.TABLE.ORGANIZERS",
2525
sortable: true,

src/configs/tableConfigs/seriesTableMap.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import SeriesTitleCell from "../../components/events/partials/SeriesTitleCell";
2-
import SeriesCreatorsCell from "../../components/events/partials/SeriesCreatorsCell";
2+
import SeriesOrganizersCell from "../../components/events/partials/SeriesOrganizersCell";
33
import SeriesContributorsCell from "../../components/events/partials/SeriesContributorsCell";
44
import SeriesDateTimeCell from "../../components/events/partials/SeriesDateTimeCell";
55
import SeriesActionsCell from "../../components/events/partials/SeriesActionsCell";
@@ -10,7 +10,7 @@ import SeriesActionsCell from "../../components/events/partials/SeriesActionsCel
1010
*/
1111
export const seriesTemplateMap = {
1212
SeriesTitleCell: SeriesTitleCell,
13-
SeriesCreatorsCell: SeriesCreatorsCell,
13+
SeriesOrganizersCell: SeriesOrganizersCell,
1414
SeriesContributorsCell: SeriesContributorsCell,
1515
SeriesDateTimeCell: SeriesDateTimeCell,
1616
SeriesActionsCell: SeriesActionsCell,

0 commit comments

Comments
 (0)