diff --git a/app/components/DataTable/components/ActionCellRenderer/index.tsx b/app/components/DataTable/components/ActionCellRenderer/index.tsx index 9f3e1754f..8a011d82c 100644 --- a/app/components/DataTable/components/ActionCellRenderer/index.tsx +++ b/app/components/DataTable/components/ActionCellRenderer/index.tsx @@ -22,6 +22,8 @@ import ImageViewer from '../ImageViewer'; import './index.scss'; type ActionCellRendererProps = { + // Finer Permission control on if row can be Edited, takes precedence over table canEdit via context of AgGridReact + canEditRowData?: boolean; context?: { canEdit?: boolean; canViewDetails?: boolean; @@ -68,8 +70,10 @@ const WrapperComponent = ({ const ActionCellRenderer = ({ data, + // Row-specific edit permissions + canEditRowData, context: { - canEdit, + canEdit: canEditTable, canViewDetails, canDelete, } = {}, @@ -83,6 +87,13 @@ const ActionCellRenderer = ({ const [showImageViewer, setShowImageViewer] = useState(false); const [columnMapping, setColumnMapping] = useState({}); + const canEdit = useMemo(() => { + if (canEditRowData === undefined) { + return canEditTable; + } + return canEditRowData; + }, [canEditRowData, canEditTable]); + useEffect(() => { if (showDetailDialog) { setColumnMapping( diff --git a/app/views/AdminView/components/Groups/columnDefs.ts b/app/views/AdminView/components/Groups/columnDefs.ts deleted file mode 100644 index 03b0a6d72..000000000 --- a/app/views/AdminView/components/Groups/columnDefs.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ColDef } from '@ag-grid-community/core'; -import { basicTooltipValueGetter } from '@/components/DataTable/components/ToolTip'; - -const descriptions = { - admin: 'all access', - 'all projects access': 'access to all projects', - 'template edit access': 'can create/edit/delete report templates', - 'appendix edit access': 'can create/edit/delete template appendix text', - 'unreviewed access': 'can view reports that have not been reviewed', - 'non-production access': 'can view reports that have non-production status', - 'germline access': 'can view germline reports', - 'report assignment access': 'can assign users to reports; bioinformatician', - 'create report access': 'can load new reports', - 'variant-text edit access': 'can create/edit/delete specific variant-text', - manager: 'can create/edit/delete nonadmin users; all other permissions within assigned projects', -}; - -const columnDefs: ColDef[] = [ - { - headerName: 'Group Name', - valueGetter: ({ data }) => data.name.toLowerCase(), - hide: false, - }, - { - headerName: 'Description', - valueGetter: ({ data }) => { - if (data.description) { - return data.description; - } - if (descriptions[data.name.toLowerCase()]) { - return descriptions[data.name.toLowerCase()]; - } - return ''; - }, - tooltipComponent: 'ToolTip', - tooltipValueGetter: basicTooltipValueGetter, - hide: false, - flex: 1, - autoHeight: true, - wrapText: true, - }, - { - headerName: 'Actions', - cellRenderer: 'ActionCellRenderer', - pinned: 'right', - sortable: false, - suppressMenu: true, - }, -]; - -export default columnDefs; diff --git a/app/views/AdminView/components/Groups/index.tsx b/app/views/AdminView/components/Groups/index.tsx index c6388eafe..728eed591 100644 --- a/app/views/AdminView/components/Groups/index.tsx +++ b/app/views/AdminView/components/Groups/index.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect, useCallback, + useMemo, } from 'react'; import { CircularProgress, @@ -9,11 +10,26 @@ import { useSnackbar } from 'notistack'; import api from '@/services/api'; import DataTable from '@/components/DataTable'; import { GroupType } from '@/common'; -import columnDefs from './columnDefs'; +import { basicTooltipValueGetter } from '@/components/DataTable/components/ToolTip'; +import useResource from '@/hooks/useResource'; import AddEditGroupDialog from './components/AddEditGroupDialog'; import './index.scss'; +const descriptions = { + admin: 'all access', + 'all projects access': 'access to all projects', + 'template edit access': 'can create/edit/delete report templates', + 'appendix edit access': 'can create/edit/delete template appendix text', + 'unreviewed access': 'can view reports that have not been reviewed', + 'non-production access': 'can view reports that have non-production status', + 'germline access': 'can view germline reports', + 'report assignment access': 'can assign users to reports; bioinformatician', + 'create report access': 'can load new reports', + 'variant-text edit access': 'can create/edit/delete specific variant-text', + manager: 'can create/edit/delete nonadmin users; all other permissions within assigned projects', +}; + const ALL_ACCESS = ['admin', 'manager', 'report assignment access', 'create report access', 'germline access', 'non-production access', 'unreviewed access', 'all projects access', 'template edit access', 'appendix edit access', 'variant-text edit access']; const Groups = (): JSX.Element => { @@ -21,6 +37,7 @@ const Groups = (): JSX.Element => { const [loading, setLoading] = useState(true); const [showDialog, setShowDialog] = useState(false); const [editData, setEditData] = useState(); + const { adminAccess, allProjectsAccess } = useResource(); const snackbar = useSnackbar(); @@ -36,6 +53,51 @@ const Groups = (): JSX.Element => { getData(); }, []); + const groupColumnDefs = useMemo(() => ([ + { + headerName: 'Group Name', + valueGetter: ({ data }) => data.name.toLowerCase(), + hide: false, + }, + { + headerName: 'Description', + valueGetter: ({ data }) => { + if (data.description) { + return data.description; + } + if (descriptions[data.name.toLowerCase()]) { + return descriptions[data.name.toLowerCase()]; + } + return ''; + }, + tooltipComponent: 'ToolTip', + tooltipValueGetter: basicTooltipValueGetter, + hide: false, + flex: 1, + autoHeight: true, + wrapText: true, + }, + { + headerName: 'Actions', + cellRenderer: 'ActionCellRenderer', + cellRendererParams: ({ data: { name } }) => { + let nextCanEdit = true; + if (name === 'admin' && !adminAccess) { + nextCanEdit = false; + } + if (name === 'all projects access' && !(adminAccess || allProjectsAccess)) { + nextCanEdit = false; + } + return ({ + canEditRowData: nextCanEdit, + }); + }, + pinned: 'right', + sortable: false, + suppressMenu: true, + }, + ]), [adminAccess, allProjectsAccess]); + const handleEditStart = (rowData) => { setShowDialog(true); setEditData(rowData); @@ -64,7 +126,7 @@ const Groups = (): JSX.Element => { <>