diff --git a/src/components/dataDisplays/HoustonSightingsDisplay.jsx b/src/components/dataDisplays/HoustonSightingsDisplay.jsx
index 29bccf5f..06a67cb5 100644
--- a/src/components/dataDisplays/HoustonSightingsDisplay.jsx
+++ b/src/components/dataDisplays/HoustonSightingsDisplay.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import ActionIcon from '../ActionIcon';
-import { cellRendererTypes } from '../dataDisplays/cellRenderers';
+import { cellRendererTypes } from './cellRenderers';
import DataDisplay from './DataDisplay';
export default function HoustonSightingsDisplay({
diff --git a/src/components/dataDisplays/cellRenderers/ActionGroupRenderer.jsx b/src/components/dataDisplays/cellRenderers/ActionGroupRenderer.jsx
new file mode 100644
index 00000000..fdb52f94
--- /dev/null
+++ b/src/components/dataDisplays/cellRenderers/ActionGroupRenderer.jsx
@@ -0,0 +1,95 @@
+import React, { useMemo } from 'react';
+import ActionIcon from '../../ActionIcon';
+
+function convertClickHandler(clickProp, value, datum) {
+ if (clickProp && typeof clickProp === 'function') {
+ return () => clickProp(value, datum);
+ }
+ return clickProp;
+}
+
+function convertHref(hrefProp, value, datum) {
+ return typeof hrefProp === 'function'
+ ? hrefProp(value, datum)
+ : hrefProp;
+}
+
+export default function ActionGroupRenderer({
+ value,
+ datum,
+ onView,
+ viewHref,
+ viewItemProps = {},
+ onEdit,
+ editHref,
+ editItemProps = {},
+ onDelete,
+ deleteHref,
+ deleteItemProps = {},
+ children,
+}) {
+ const showView = viewHref || onView;
+ const showEdit = editHref || onEdit;
+ const showDelete = deleteHref || onDelete;
+
+ const {
+ handleView,
+ handleEdit,
+ handleDelete,
+ finalViewHref,
+ finalEditHref,
+ finalDeleteHref,
+ } = useMemo(
+ () => ({
+ handleView: convertClickHandler(onView, value, datum),
+ handleEdit: convertClickHandler(onEdit, value, datum),
+ handleDelete: convertClickHandler(onDelete, value, datum),
+ finalViewHref: convertHref(viewHref, value, datum),
+ finalEditHref: convertHref(editHref, value, datum),
+ finalDeleteHref: convertHref(deleteHref, value, datum),
+ }),
+ [
+ value,
+ datum,
+ onView,
+ onEdit,
+ onDelete,
+ viewHref,
+ editHref,
+ deleteHref,
+ ],
+ );
+
+ return (
+
+ {showView && (
+
+ )}
+ {showEdit && (
+
+ )}
+ {showDelete && (
+
+ )}
+ {children}
+
+ );
+}
diff --git a/src/components/dataDisplays/cellRenderers/index.js b/src/components/dataDisplays/cellRenderers/index.js
index 0763ba44..bc779250 100644
--- a/src/components/dataDisplays/cellRenderers/index.js
+++ b/src/components/dataDisplays/cellRenderers/index.js
@@ -1,4 +1,5 @@
import DefaultRenderer from './DefaultRenderer';
+import ActionGroupRenderer from './ActionGroupRenderer';
import UserRenderer from './UserRenderer';
import LocationRenderer from './LocationRenderer';
import SpecifiedTimeRenderer from './SpecifiedTimeRenderer';
@@ -11,6 +12,7 @@ import SocialGroupRoleRenderer from './SocialGroupRoleRenderer';
export const cellRendererTypes = {
default: 'default',
+ actionGroup: 'actionGroup',
user: 'user',
location: 'location',
specifiedTime: 'specifiedTime',
@@ -24,6 +26,7 @@ export const cellRendererTypes = {
export const cellRenderers = {
[cellRendererTypes.default]: DefaultRenderer,
+ [cellRendererTypes.actionGroup]: ActionGroupRenderer,
[cellRendererTypes.user]: UserRenderer,
[cellRendererTypes.location]: LocationRenderer,
[cellRendererTypes.specifiedTime]: SpecifiedTimeRenderer,
diff --git a/src/pages/fieldManagement/settings/CustomFieldTable.jsx b/src/pages/fieldManagement/settings/CustomFieldTable.jsx
index aca7d70d..5c7ae78a 100644
--- a/src/pages/fieldManagement/settings/CustomFieldTable.jsx
+++ b/src/pages/fieldManagement/settings/CustomFieldTable.jsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useState } from 'react';
+import React, { useCallback, useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
import { get } from 'lodash-es';
@@ -6,8 +6,8 @@ import Grid from '@material-ui/core/Grid';
import Tooltip from '@material-ui/core/Tooltip';
import AddIcon from '@material-ui/icons/Add';
+import { cellRendererTypes } from '../../../components/dataDisplays/cellRenderers';
import useRemoveCustomField from '../../../models/site/useRemoveCustomField';
-import ActionIcon from '../../../components/ActionIcon';
import ButtonLink from '../../../components/ButtonLink';
import ConfirmDelete from '../../../components/ConfirmDelete';
import Text from '../../../components/Text';
@@ -62,6 +62,22 @@ export default function CustomFieldTable({
);
const fieldTypeName = fieldTypeDefinition.name;
+ const onViewCustomField = useCallback((_, field) => {
+ setPreviewInitialValue(field.defaultValue);
+ setPreviewField(field);
+ }, []);
+
+ const deriveEditHref = useCallback(
+ (_, field) =>
+ `/settings/fields/save-custom-field/${fieldTypeName}/${field.id}`,
+ [fieldTypeName],
+ );
+
+ const onDeleteCustomField = useCallback(
+ (_, field) => setDeleteField(field),
+ [],
+ );
+
const tableColumns = useMemo(
() => [
{
@@ -89,30 +105,16 @@ export default function CustomFieldTable({
name: 'actions',
labelId: 'ACTIONS',
options: {
- customBodyRender: (_, field) => (
-
-
{
- setPreviewInitialValue(field.defaultValue);
- setPreviewField(field);
- }}
- />
-
- setDeleteField(field)}
- />
-
- ),
+ cellRenderer: cellRendererTypes.actionGroup,
+ cellRendererProps: {
+ onView: onViewCustomField,
+ editHref: deriveEditHref,
+ onDelete: onDeleteCustomField,
+ },
},
},
],
- [intl, fieldTypeName],
+ [onViewCustomField, deriveEditHref, onDeleteCustomField],
);
const onCloseConfirmDelete = () => {