Skip to content

Commit edbcbec

Browse files
authored
Reduce duplicate code in action cells (#1018)
* Reduce duplicate code in action cells Mostly by turning the button that's copy-pasted everywhere into its own component. * Fix simple warnings
1 parent d67e437 commit edbcbec

17 files changed

Lines changed: 304 additions & 366 deletions

src/components/configuration/partials/ThemesActionsCell.tsx

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import React, { useRef } from "react";
2-
import { useTranslation } from "react-i18next";
3-
import ConfirmModal from "../../shared/ConfirmModal";
42
import {
53
fetchThemeDetails,
64
fetchUsage,
75
} from "../../../slices/themeDetailsSlice";
8-
import { getUserInformation } from "../../../selectors/userInfoSelectors";
9-
import { hasAccess } from "../../../utils/utils";
10-
import { useAppDispatch, useAppSelector } from "../../../store";
6+
import { useAppDispatch } from "../../../store";
117
import { deleteTheme, ThemeDetailsType } from "../../../slices/themeSlice";
12-
import { Tooltip } from "../../shared/Tooltip";
138
import ThemeDetails from "./wizard/ThemeDetails";
9+
import { ActionCellDelete } from "../../shared/ActionCellDelete";
10+
import { IconButton } from "../../shared/IconButton";
1411
import { Modal, ModalHandle } from "../../shared/modals/Modal";
12+
import { useTranslation } from "react-i18next";
1513

1614
/**
1715
* This component renders the action cells of themes in the table view
@@ -24,15 +22,8 @@ const ThemesActionsCell = ({
2422
const { t } = useTranslation();
2523
const dispatch = useAppDispatch();
2624

27-
const deleteConfirmationModalRef = useRef<ModalHandle>(null);
2825
const detailsModalRef = useRef<ModalHandle>(null);
2926

30-
const user = useAppSelector(state => getUserInformation(state));
31-
32-
const hideDeleteConfirmation = () => {
33-
deleteConfirmationModalRef.current?.close?.();
34-
};
35-
3627
const hideThemeDetails = () => {
3728
detailsModalRef.current?.close?.();
3829
};
@@ -51,14 +42,12 @@ const ThemesActionsCell = ({
5142
return (
5243
<>
5344
{/* edit themes */}
54-
{hasAccess("ROLE_UI_THEMES_EDIT", user) && (
55-
<Tooltip title={t("CONFIGURATION.THEMES.TABLE.TOOLTIP.DETAILS")}>
56-
<button
57-
onClick={() => showThemeDetails()}
58-
className="button-like-anchor more"
59-
/>
60-
</Tooltip>
61-
)}
45+
<IconButton
46+
callback={() => showThemeDetails()}
47+
iconClassname={"more"}
48+
editAccessRole={"ROLE_UI_THEMES_EDIT"}
49+
tooltipText={"CONFIGURATION.THEMES.TABLE.TOOLTIP.DETAILS"}
50+
/>
6251

6352
{/* themes details modal */}
6453
<Modal
@@ -71,22 +60,13 @@ const ThemesActionsCell = ({
7160
</Modal>
7261

7362
{/* delete themes */}
74-
{hasAccess("ROLE_UI_THEMES_DELETE", user) && (
75-
<Tooltip title={t("CONFIGURATION.THEMES.TABLE.TOOLTIP.DELETE")}>
76-
<button
77-
onClick={() => deleteConfirmationModalRef.current?.open()}
78-
className="button-like-anchor remove ng-scope ng-isolate-scope"
79-
/>
80-
</Tooltip>
81-
)}
82-
83-
<ConfirmModal
84-
close={hideDeleteConfirmation}
85-
resourceName={row.name}
63+
<ActionCellDelete
64+
editAccessRole={"ROLE_UI_THEMES_DELETE"}
65+
tooltipText={"CONFIGURATION.THEMES.TABLE.TOOLTIP.DELETE"}
8666
resourceId={row.id}
67+
resourceName={row.name}
68+
resourceType={"THEME"}
8769
deleteMethod={deletingTheme}
88-
resourceType="THEME"
89-
modalRef={deleteConfirmationModalRef}
9070
/>
9171
</>
9272
);

src/components/events/partials/EventActionCell.tsx

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useRef } from "react";
22
import { useTranslation } from "react-i18next";
3-
import ConfirmModal from "../../shared/ConfirmModal";
43
import EmbeddingCodeModal from "./modals/EmbeddingCodeModal";
54
import { getUserInformation } from "../../../selectors/userInfoSelectors";
65
import { hasAccess } from "../../../utils/utils";
@@ -17,6 +16,8 @@ import {
1716
import { Event, deleteEvent } from "../../../slices/eventSlice";
1817
import { Tooltip } from "../../shared/Tooltip";
1918
import { openModal } from "../../../slices/eventDetailsSlice";
19+
import { ActionCellDelete } from "../../shared/ActionCellDelete";
20+
import { IconButton } from "../../shared/IconButton";
2021
import { Modal, ModalHandle } from "../../shared/modals/Modal";
2122

2223
/**
@@ -30,16 +31,11 @@ const EventActionCell = ({
3031
const { t } = useTranslation();
3132
const dispatch = useAppDispatch();
3233

33-
const deleteConfirmationModalRef = useRef<ModalHandle>(null);
3434
const seriesDetailsModalRef = useRef<ModalHandle>(null);
3535
const embeddingCodeModalRef = useRef<ModalHandle>(null);
3636

3737
const user = useAppSelector(state => getUserInformation(state));
3838

39-
const hideDeleteConfirmation = () => {
40-
deleteConfirmationModalRef.current?.close?.()
41-
};
42-
4339
const deletingEvent = (id: string) => {
4440
dispatch(deleteEvent(id));
4541
};
@@ -95,44 +91,32 @@ const EventActionCell = ({
9591
)}
9692

9793
{/* Open event details */}
98-
{hasAccess("ROLE_UI_EVENTS_DETAILS_VIEW", user) && (
99-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.DETAILS")}>
100-
<button
101-
onClick={() => onClickEventDetails()}
102-
className="button-like-anchor more"
103-
/>
104-
</Tooltip>
105-
)}
94+
<IconButton
95+
callback={onClickEventDetails}
96+
iconClassname={"more"}
97+
editAccessRole={"ROLE_UI_EVENTS_DETAILS_VIEW"}
98+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.DETAILS"}
99+
/>
106100

107101
{/* If event belongs to a series then the corresponding series details can be opened */}
108-
{!!row.series && hasAccess("ROLE_UI_SERIES_DETAILS_VIEW", user) && (
109-
<Tooltip title={t("EVENTS.SERIES.TABLE.TOOLTIP.DETAILS")}>
110-
<button
111-
onClick={() => onClickSeriesDetails()}
112-
className="button-like-anchor more-series"
113-
/>
114-
</Tooltip>
102+
{!!row.series && (
103+
<IconButton
104+
callback={onClickSeriesDetails}
105+
iconClassname={"more-series"}
106+
editAccessRole={"ROLE_UI_SERIES_DETAILS_VIEW"}
107+
tooltipText={"EVENTS.SERIES.TABLE.TOOLTIP.DETAILS"}
108+
/>
115109
)}
116110

117111
{/* Delete an event */}
118112
{/*TODO: needs to be checked if event is published */}
119-
{hasAccess("ROLE_UI_EVENTS_DELETE", user) && (
120-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.DELETE")}>
121-
<button
122-
onClick={() => deleteConfirmationModalRef.current?.open()}
123-
className="button-like-anchor remove"
124-
/>
125-
</Tooltip>
126-
)}
127-
128-
{/* Confirmation for deleting an event*/}
129-
<ConfirmModal
130-
close={hideDeleteConfirmation}
131-
resourceName={row.title}
132-
resourceType="EVENT"
113+
<ActionCellDelete
114+
editAccessRole={"ROLE_UI_EVENTS_DELETE"}
115+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.DELETE"}
133116
resourceId={row.id}
117+
resourceName={row.title}
118+
resourceType={"EVENT"}
134119
deleteMethod={deletingEvent}
135-
modalRef={deleteConfirmationModalRef}
136120
/>
137121

138122
{/* If the event has an preview then the editor can be opened and status if it needs to be cut is shown */}
@@ -156,54 +140,48 @@ const EventActionCell = ({
156140

157141
{/* If the event has comments and no open comments then the comment tab of event details can be opened directly */}
158142
{row.has_comments && !row.has_open_comments && (
159-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.COMMENTS")}>
160-
<button
161-
onClick={() => onClickComments()}
162-
className="button-like-anchor comments"
163-
/>
164-
</Tooltip>
143+
<IconButton
144+
callback={() => onClickComments()}
145+
iconClassname={"comments"}
146+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.COMMENTS"}
147+
/>
165148
)}
166149

167150
{/* If the event has comments and open comments then the comment tab of event details can be opened directly */}
168151
{row.has_comments && row.has_open_comments && (
169-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.COMMENTS")}>
170-
<button
171-
onClick={() => onClickComments()}
172-
className="button-like-anchor comments-open"
173-
/>
174-
</Tooltip>
152+
<IconButton
153+
callback={() => onClickComments()}
154+
iconClassname={"comments-open"}
155+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.COMMENTS"}
156+
/>
175157
)}
176158

177159
{/*If the event is in in a paused workflow state then a warning icon is shown and workflow tab of event
178-
details can be opened directly */}
160+
details can be opened directly */}
179161
{row.workflow_state === "PAUSED" &&
180-
hasAccess("ROLE_UI_EVENTS_DETAILS_WORKFLOWS_EDIT", user) && (
181-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.PAUSED_WORKFLOW")}>
182-
<button
183-
onClick={() => onClickWorkflow()}
184-
className="button-like-anchor fa fa-warning"
185-
/>
186-
</Tooltip>
187-
)}
162+
<IconButton
163+
callback={() => onClickWorkflow()}
164+
iconClassname={"fa fa-warning"}
165+
editAccessRole={"ROLE_UI_EVENTS_DETAILS_WORKFLOWS_EDIT"}
166+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.PAUSED_WORKFLOW"}
167+
/>
168+
}
188169

189170
{/* Open assets tab of event details directly*/}
190-
{hasAccess("ROLE_UI_EVENTS_DETAILS_ASSETS_VIEW", user) && (
191-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.ASSETS")}>
192-
<button
193-
onClick={() => onClickAssets()}
194-
className="button-like-anchor fa fa-folder-open"
195-
/>
196-
</Tooltip>
197-
)}
171+
<IconButton
172+
callback={() => onClickAssets()}
173+
iconClassname={"fa fa-folder-open"}
174+
editAccessRole={"ROLE_UI_EVENTS_DETAILS_ASSETS_VIEW"}
175+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.ASSETS"}
176+
/>
177+
198178
{/* Open dialog for embedded code*/}
199-
{hasAccess("ROLE_UI_EVENTS_EMBEDDING_CODE_VIEW", user) && (
200-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.EMBEDDING_CODE")}>
201-
<button
202-
onClick={() => showEmbeddingCodeModal()}
203-
className="button-like-anchor fa fa-link"
204-
/>
205-
</Tooltip>
206-
)}
179+
<IconButton
180+
callback={() => showEmbeddingCodeModal()}
181+
iconClassname={"fa fa-link"}
182+
editAccessRole={"ROLE_UI_EVENTS_EMBEDDING_CODE_VIEW"}
183+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.EMBEDDING_CODE"}
184+
/>
207185

208186
{/* Embedding Code Modal */}
209187
<Modal

src/components/events/partials/EventsDateCell.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { getFilters } from "../../../selectors/tableFilterSelectors";
66
import { useAppDispatch, useAppSelector } from "../../../store";
77
import { fetchEvents } from "../../../slices/eventSlice";
88
import { renderValidDate } from "../../../utils/dateUtils";
9-
import { Tooltip } from "../../shared/Tooltip";
109
import { Event } from "../../../slices/eventSlice";
10+
import { IconButton } from "../../shared/IconButton";
1111

1212
/**
1313
* This component renders the start date cells of events in the table view
@@ -43,14 +43,13 @@ const EventsDateCell = ({
4343

4444
return (
4545
// Link template for start date of event
46-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.START")}>
47-
<button
48-
className="button-like-anchor crosslink"
49-
onClick={() => addFilter(row.date)}
50-
>
51-
{t("dateFormats.date.short", { date: renderValidDate(row.date) })}
52-
</button>
53-
</Tooltip>
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>
5453
);
5554
};
5655

src/components/events/partials/EventsLocationCell.tsx

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from "react";
2-
import { useTranslation } from "react-i18next";
32
import { getFilters } from "../../../selectors/tableFilterSelectors";
43
import { editFilterValue } from "../../../slices/tableFilterSlice";
54
import { loadEventsIntoTable } from "../../../thunks/tableThunks";
65
import { useAppDispatch, useAppSelector } from "../../../store";
76
import { fetchEvents } from "../../../slices/eventSlice";
8-
import { Tooltip } from "../../shared/Tooltip";
97
import { Event } from "../../../slices/eventSlice";
8+
import { IconButton } from "../../shared/IconButton";
109

1110
/**
1211
* This component renders the location cells of events in the table view
@@ -16,7 +15,6 @@ const EventsLocationCell = ({
1615
}: {
1716
row: Event
1817
}) => {
19-
const { t } = useTranslation();
2018
const dispatch = useAppDispatch();
2119

2220
const filterMap = useAppSelector(state => getFilters(state));
@@ -33,14 +31,13 @@ const EventsLocationCell = ({
3331

3432
return (
3533
// Link template for location of event
36-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.LOCATION")}>
37-
<button
38-
className="button-like-anchor crosslink"
39-
onClick={() => addFilter(row.location)}
40-
>
41-
{row.location}
42-
</button>
43-
</Tooltip>
34+
<IconButton
35+
callback={() => addFilter(row.location)}
36+
iconClassname={"crosslink"}
37+
tooltipText={"EVENTS.EVENTS.TABLE.TOOLTIP.LOCATION"}
38+
>
39+
{row.location}
40+
</IconButton>
4441
);
4542
};
4643

src/components/events/partials/EventsPresentersCell.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from "react";
2-
import { useTranslation } from "react-i18next";
32
import { getFilters } from "../../../selectors/tableFilterSelectors";
43
import { editFilterValue } from "../../../slices/tableFilterSlice";
54
import { loadEventsIntoTable } from "../../../thunks/tableThunks";
65
import { useAppDispatch, useAppSelector } from "../../../store";
76
import { fetchEvents } from "../../../slices/eventSlice";
8-
import { Tooltip } from "../../shared/Tooltip";
97
import { Event } from "../../../slices/eventSlice";
8+
import { IconButton } from "../../shared/IconButton";
109

1110
/**
1211
* This component renders the presenters cells of events in the table view
@@ -16,7 +15,6 @@ const EventsPresentersCell = ({
1615
}: {
1716
row: Event
1817
}) => {
19-
const { t } = useTranslation();
2018
const dispatch = useAppDispatch();
2119

2220
const filterMap = useAppSelector(state => getFilters(state));
@@ -37,14 +35,14 @@ const EventsPresentersCell = ({
3735
// Link template for presenter of event
3836
// Repeat for each presenter
3937
row.presenters.map((presenter, key) => (
40-
<Tooltip title={t("EVENTS.EVENTS.TABLE.TOOLTIP.PRESENTER")} key={key}>
41-
<button
42-
className="button-like-anchor metadata-entry"
43-
onClick={() => addFilter(presenter)}
44-
>
45-
{presenter}
46-
</button>
47-
</Tooltip>
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>
4846
))
4947
);
5048
};

0 commit comments

Comments
 (0)