diff --git a/frontend/src/utils/grid/cellRenderers.jsx b/frontend/src/utils/grid/cellRenderers.jsx index 60ad2e761..7563007f4 100644 --- a/frontend/src/utils/grid/cellRenderers.jsx +++ b/frontend/src/utils/grid/cellRenderers.jsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import BCBadge from '@/components/BCBadge' import BCBox from '@/components/BCBox' import { roles } from '@/constants/roles' @@ -5,8 +6,9 @@ import { getAllFuelCodeStatuses, getAllOrganizationStatuses } from '@/constants/statuses' -import { Stack } from '@mui/material' import { Link, useLocation } from 'react-router-dom' +import { useState, useRef, useEffect, useCallback } from 'react' +import colors from '@/themes/base/colors' export const TextRenderer = (props) => { return ( @@ -35,7 +37,6 @@ export const LinkRenderer = (props) => { } export const StatusRenderer = (props) => { - const location = useLocation() return ( { ) } -export const CommonArrayRenderer = (props) => { - const location = useLocation() - const options = Array.isArray(props.value) - ? props.value - : props.value.split(',') - const chipContent = ( - - {options.map((mode) => ( - - ))} - - ) - return props.disableLink ? ( - chipContent - ) : ( - - {chipContent} - - ) -} - export const TransactionStatusRenderer = (props) => { const statusArr = [ 'Draft', @@ -321,52 +269,6 @@ export const ReportsStatusRenderer = (props) => { ) } -// if the status of the user is in-active then don't show their previously held roles -export const RoleRenderer = (props) => { - const location = useLocation() - return ( - - - - {props.data.isActive && - props.data.roles - .filter( - (r) => r.name !== roles.government && r.name !== roles.supplier - ) - .map((role) => ( - - ))}{' '} - - - - ) -} - export const RoleSpanRenderer = (props) => ( <> {props.data.roles @@ -390,3 +292,274 @@ export const RoleSpanRenderer = (props) => ( ))} ) + +const GenericChipRenderer = ({ + value, + disableLink = false, + renderChip = defaultRenderChip, + renderOverflowChip = defaultRenderOverflowChip, + chipConfig = {}, + ...props +}) => { + const location = useLocation() + const { colDef, api } = props + const containerRef = useRef(null) + const [visibleChips, setVisibleChips] = useState([]) + const [hiddenChipsCount, setHiddenChipsCount] = useState(0) + + const options = Array.isArray(value) + ? value + : value + .split(',') + .map((item) => item.trim()) + .filter(Boolean) + + const calculateChipWidths = useCallback(() => { + if (!containerRef.current) return { visibleChips: [], hiddenChipsCount: 0 } + + const containerWidth = containerRef.current.offsetWidth || 200 // Fallback width + let totalWidth = 0 + const chipWidths = [] + + for (let i = 0; i < options.length; i++) { + const chipText = options[i] + const chipTextWidth = chipText.length * 6 // Assuming 6px per character + const newTotalWidth = totalWidth + chipTextWidth + 32 + 20 // Adding 32px for padding and 20px for overflow counter chip + + if (newTotalWidth <= containerWidth) { + chipWidths.push({ + text: chipText, + width: chipTextWidth + 32, + ...chipConfig + }) + totalWidth = newTotalWidth + } else { + return { + visibleChips: chipWidths, + hiddenChipsCount: options.length - chipWidths.length + } + } + } + + return { + visibleChips: options.map((text) => ({ + text, + width: text.length * 6 + 32, + ...chipConfig + })), + hiddenChipsCount: 0 + } + }, [options]) + + // Initial render and resize handling + useEffect(() => { + // Calculate and set chips on initial render + const { visibleChips, hiddenChipsCount } = calculateChipWidths() + setVisibleChips(visibleChips) + setHiddenChipsCount(hiddenChipsCount) + + // Resize listener + const resizeObserver = new ResizeObserver(() => { + const { visibleChips, hiddenChipsCount } = calculateChipWidths() + setVisibleChips(visibleChips) + setHiddenChipsCount(hiddenChipsCount) + }) + if (containerRef.current) { + resizeObserver.observe(containerRef.current) + } + + // Column resize listener for ag-Grid + const resizeListener = (event) => { + const resizedColumn = event.column + if (resizedColumn.getColId() === colDef.field) { + const { visibleChips, hiddenChipsCount } = calculateChipWidths() + setVisibleChips(visibleChips) + setHiddenChipsCount(hiddenChipsCount) + } + } + + if (api) { + api.addEventListener('columnResized', resizeListener) + + // Cleanup + return () => { + api.removeEventListener('columnResized', resizeListener) + resizeObserver.disconnect() + } + } + + return () => { + resizeObserver.disconnect() + } + }, [value, api, colDef]) + + const chipContent = ( +
+ {visibleChips.map(renderChip)} + {renderOverflowChip(hiddenChipsCount)} +
+ ) + + return disableLink ? ( + chipContent + ) : ( + + {chipContent} + + ) +} + +// Default Render Chip Function for CommonArrayRenderer +const defaultRenderChip = (chip) => ( + + {chip.text} + +) + +// Default Overflow Chip for CommonArrayRenderer +const defaultRenderOverflowChip = (hiddenChipsCount) => + hiddenChipsCount > 0 && ( + + +{hiddenChipsCount} + + ) + +// Role Specific Render Chip Function +const roleRenderChip = (chip, isGovernmentRole = false) => ( + +) + +// Role Specific Overflow Chip +const roleRenderOverflowChip = (hiddenChipsCount, isGovernmentRole = false) => + hiddenChipsCount > 0 && ( + + +{hiddenChipsCount} + + ) + +export default GenericChipRenderer + +export const CommonArrayRenderer = (props) => ( + +) + +export const RoleRenderer = (props) => { + const { value } = props + const [isGovernmentRole, setIsGovernmentRole] = useState(false) + + const filteredRoles = Array.isArray(value) + ? value + : value + .split(',') + .map((role) => role.trim()) + .filter((role) => role !== roles.government && role !== roles.supplier) + + useEffect(() => { + setIsGovernmentRole(value.includes(roles.government)) + }, [value]) + + return ( + roleRenderChip(chip, isGovernmentRole)} + renderOverflowChip={(count) => + roleRenderOverflowChip(count, isGovernmentRole) + } + /> + ) +} diff --git a/frontend/src/views/Admin/AdminMenu/components/Users.jsx b/frontend/src/views/Admin/AdminMenu/components/Users.jsx index bcd65bc76..28f2e021b 100644 --- a/frontend/src/views/Admin/AdminMenu/components/Users.jsx +++ b/frontend/src/views/Admin/AdminMenu/components/Users.jsx @@ -51,19 +51,6 @@ export const Users = () => { }) const gridRef = useRef() - const getRowHeight = useCallback((params) => { - const actualWidth = params.api.getColumn('role').getActualWidth() - return calculateRowHeight(actualWidth, params.data?.roles) - }, []) - - const onColumnResized = useCallback((params) => { - const actualWidth = params.api.getColumn('role').getActualWidth() - params.api.resetRowHeights() - params.api.forEachNode((node) => { - const rowHeight = calculateRowHeight(actualWidth, node.data?.roles) - node.setRowHeight(rowHeight) - }) - }, []) useEffect(() => { if (location.state?.message) { setAlertMessage(location.state.message) @@ -115,8 +102,6 @@ export const Users = () => { handleRowClicked={handleRowClicked} enableResetButton={false} enableCopyButton={false} - getRowHeight={getRowHeight} - onColumnResized={onColumnResized} />
diff --git a/frontend/src/views/Admin/AdminMenu/components/_schema.js b/frontend/src/views/Admin/AdminMenu/components/_schema.js index 23a63525f..7e9f3a303 100644 --- a/frontend/src/views/Admin/AdminMenu/components/_schema.js +++ b/frontend/src/views/Admin/AdminMenu/components/_schema.js @@ -28,8 +28,6 @@ export const usersColumnDefs = (t) => [ params.data.isActive ? params.data.roles.map((role) => role.name).join(', ') : '', - flex: 1, - minWidth: 300, sortable: false, suppressHeaderMenuButton: true, filterParams: { diff --git a/frontend/src/views/Organizations/ViewOrganization/ViewOrganization.jsx b/frontend/src/views/Organizations/ViewOrganization/ViewOrganization.jsx index 4cc1abd8b..2bf32af03 100644 --- a/frontend/src/views/Organizations/ViewOrganization/ViewOrganization.jsx +++ b/frontend/src/views/Organizations/ViewOrganization/ViewOrganization.jsx @@ -75,20 +75,6 @@ export const ViewOrganization = () => { } }, []) - const getRowHeight = useCallback((params) => { - const actualWidth = params.api.getColumn('role').getActualWidth() - return calculateRowHeight(actualWidth, params.data?.roles) - }, []) - - const onColumnResized = useCallback((params) => { - const actualWidth = params.api.getColumn('role').getActualWidth() - params.api.resetRowHeights() - params.api.forEachNode((node) => { - const rowHeight = calculateRowHeight(actualWidth, node.data?.roles) - node.setRowHeight(rowHeight) - }) - }, []) - const gridOptions = { overlayNoRowsTemplate: 'No users found', includeHiddenColumnsInQuickFilter: true @@ -348,8 +334,6 @@ export const ViewOrganization = () => { handleRowClicked={handleRowClicked} enableCopyButton={false} enableResetButton={false} - getRowHeight={getRowHeight} - onColumnResized={onColumnResized} />