Enhance PermissionsMatrix with hover effects and refactor column handling
- Added hover effect to the permissions matrix table cells, improving visual feedback for user interactions. - Refactored column handling by introducing a new utility function for setting column index properties. - Replaced state management for hovered columns with a ref to optimize performance and reduce unnecessary re-renders. - Updated event handling for mouse over and leave actions to enhance user experience in the permissions matrix.
This commit is contained in:
parent
0b501a11c6
commit
76d00a8be1
@ -1337,6 +1337,29 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.permissions-matrix:hover .ant-table-tbody > tr > .ant-table-cell {
|
||||||
|
box-shadow: inset 0 0 0 100vmax
|
||||||
|
color-mix(
|
||||||
|
in srgb,
|
||||||
|
var(--color-text)
|
||||||
|
calc(
|
||||||
|
4% *
|
||||||
|
(
|
||||||
|
1 -
|
||||||
|
min(
|
||||||
|
1,
|
||||||
|
abs(
|
||||||
|
calc(
|
||||||
|
var(--permissions-col, 0) - var(--permissions-hovered-col, -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.permissions-matrix-table .permissions-matrix-group-row > .ant-table-cell {
|
.permissions-matrix-table .permissions-matrix-group-row > .ant-table-cell {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
background-color: color-mix(
|
background-color: color-mix(
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useState,
|
useState,
|
||||||
createElement,
|
createElement,
|
||||||
useContext
|
useContext,
|
||||||
|
useRef
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Table, Flex, Tooltip, Button } from 'antd'
|
import { Table, Flex, Tooltip, Button } from 'antd'
|
||||||
@ -21,6 +22,11 @@ import { CaretRightOutlined } from '@ant-design/icons'
|
|||||||
|
|
||||||
const DEFAULT_SCROLL_HEIGHT = 'calc(var(--unit-100vh) - 258px)'
|
const DEFAULT_SCROLL_HEIGHT = 'calc(var(--unit-100vh) - 258px)'
|
||||||
|
|
||||||
|
const getColumnIndexProps = (columnIndex) => ({
|
||||||
|
'data-col': String(columnIndex),
|
||||||
|
style: { '--permissions-col': String(columnIndex) }
|
||||||
|
})
|
||||||
|
|
||||||
const getPermissionState = (permissions, modelName, actionName) => {
|
const getPermissionState = (permissions, modelName, actionName) => {
|
||||||
const value = permissions?.[modelName]?.[actionName]
|
const value = permissions?.[modelName]?.[actionName]
|
||||||
if (value === true) return true
|
if (value === true) return true
|
||||||
@ -314,7 +320,21 @@ const PermissionsMatrix = ({
|
|||||||
[models]
|
[models]
|
||||||
)
|
)
|
||||||
const [expandedRowKeys, setExpandedRowKeys] = useState(null)
|
const [expandedRowKeys, setExpandedRowKeys] = useState(null)
|
||||||
const [hoveredColumnKey, setHoveredColumnKey] = useState(null)
|
const hoveredColumnIndexRef = useRef(null)
|
||||||
|
|
||||||
|
const handleMatrixMouseOver = useCallback((event) => {
|
||||||
|
const cell = event.target.closest('.ant-table-cell')
|
||||||
|
if (!cell || !event.currentTarget.contains(cell)) return
|
||||||
|
const next = cell.getAttribute('data-col')
|
||||||
|
if (!next || hoveredColumnIndexRef.current === next) return
|
||||||
|
hoveredColumnIndexRef.current = next
|
||||||
|
event.currentTarget.style.setProperty('--permissions-hovered-col', next)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleMatrixMouseLeave = useCallback((event) => {
|
||||||
|
hoveredColumnIndexRef.current = null
|
||||||
|
event.currentTarget.style.removeProperty('--permissions-hovered-col')
|
||||||
|
}, [])
|
||||||
|
|
||||||
const resolvedExpandedRowKeys = useMemo(
|
const resolvedExpandedRowKeys = useMemo(
|
||||||
() => expandedRowKeys ?? dataSource.map((row) => row.key),
|
() => expandedRowKeys ?? dataSource.map((row) => row.key),
|
||||||
@ -339,17 +359,6 @@ const PermissionsMatrix = ({
|
|||||||
[dataSource]
|
[dataSource]
|
||||||
)
|
)
|
||||||
|
|
||||||
const getColumnHoverProps = useCallback(
|
|
||||||
(columnKey, isHeader = false) => ({
|
|
||||||
onMouseEnter: () => setHoveredColumnKey(columnKey),
|
|
||||||
className:
|
|
||||||
!isHeader && hoveredColumnKey === columnKey
|
|
||||||
? 'ant-table-cell-row-hover'
|
|
||||||
: undefined
|
|
||||||
}),
|
|
||||||
[hoveredColumnKey]
|
|
||||||
)
|
|
||||||
|
|
||||||
var adjustedScrollHeight = scrollHeight
|
var adjustedScrollHeight = scrollHeight
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
adjustedScrollHeight = 'calc(var(--unit-100vh) - 298px)'
|
adjustedScrollHeight = 'calc(var(--unit-100vh) - 298px)'
|
||||||
@ -463,8 +472,8 @@ const PermissionsMatrix = ({
|
|||||||
dataIndex: 'label',
|
dataIndex: 'label',
|
||||||
fixed: isMobile ? undefined : 'left',
|
fixed: isMobile ? undefined : 'left',
|
||||||
width: 280,
|
width: 280,
|
||||||
onHeaderCell: () => getColumnHoverProps('model', true),
|
onHeaderCell: () => getColumnIndexProps(1),
|
||||||
onCell: () => getColumnHoverProps('model'),
|
onCell: () => getColumnIndexProps(1),
|
||||||
render: (label, record) => {
|
render: (label, record) => {
|
||||||
const recordModels = getRecordModels(record)
|
const recordModels = getRecordModels(record)
|
||||||
const aggregate = getAggregatePermissionState(
|
const aggregate = getAggregatePermissionState(
|
||||||
@ -536,7 +545,7 @@ const PermissionsMatrix = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionColumns = actions.map((action) => {
|
const actionColumns = actions.map((action, actionIndex) => {
|
||||||
const columnAggregate = getAggregatePermissionState(
|
const columnAggregate = getAggregatePermissionState(
|
||||||
getColumnPermissionStates(permissions, models, action, inherit)
|
getColumnPermissionStates(permissions, models, action, inherit)
|
||||||
)
|
)
|
||||||
@ -561,8 +570,8 @@ const PermissionsMatrix = ({
|
|||||||
key: action.name,
|
key: action.name,
|
||||||
width: 48,
|
width: 48,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
onHeaderCell: () => getColumnHoverProps(action.name, true),
|
onHeaderCell: () => getColumnIndexProps(actionIndex + 2),
|
||||||
onCell: () => getColumnHoverProps(action.name),
|
onCell: () => getColumnIndexProps(actionIndex + 2),
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const recordModels = getRecordModels(record)
|
const recordModels = getRecordModels(record)
|
||||||
const applicable = recordModels.filter((model) =>
|
const applicable = recordModels.filter((model) =>
|
||||||
@ -594,7 +603,6 @@ const PermissionsMatrix = ({
|
|||||||
return [modelColumn, ...actionColumns]
|
return [modelColumn, ...actionColumns]
|
||||||
}, [
|
}, [
|
||||||
actions,
|
actions,
|
||||||
getColumnHoverProps,
|
|
||||||
handleCycle,
|
handleCycle,
|
||||||
handleCycleColumn,
|
handleCycleColumn,
|
||||||
handleCycleModels,
|
handleCycleModels,
|
||||||
@ -609,7 +617,11 @@ const PermissionsMatrix = ({
|
|||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onMouseLeave={() => setHoveredColumnKey(null)}>
|
<div
|
||||||
|
className='permissions-matrix'
|
||||||
|
onMouseOver={handleMatrixMouseOver}
|
||||||
|
onMouseLeave={handleMatrixMouseLeave}
|
||||||
|
>
|
||||||
<Table
|
<Table
|
||||||
className='dashboard-table permissions-matrix-table'
|
className='dashboard-table permissions-matrix-table'
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user