1+ import { InfoOutlined } from '@mui/icons-material' ;
12import AddIcon from '@mui/icons-material/Add' ;
23import ClearIcon from '@mui/icons-material/Clear' ;
34import DeleteIcon from '@mui/icons-material/Delete' ;
@@ -6,12 +7,16 @@ import SaveAsIcon from '@mui/icons-material/SaveAs';
67import {
78 Box ,
89 Button ,
10+ IconButton ,
911 ListItemIcon ,
1012 ListItemText ,
1113 MenuItem ,
1214 Link as MuiLink ,
1315 TableCellBaseProps ,
16+ Tooltip ,
17+ Typography ,
1418} from '@mui/material' ;
19+ import Grid from '@mui/material/Grid2' ;
1520import {
1621 MaterialReactTable ,
1722 useMaterialReactTable ,
@@ -93,8 +98,14 @@ export function ItemsTable(props: ItemTableProps) {
9398 const { data : usageStatusData , isLoading : isLoadingUsageStatus } =
9499 useGetUsageStatuses ( ) ;
95100
96- const { encodedSparesFilter, isLoading : isLoadingSparesDefinition } =
97- useSparesFilterState ( ) ;
101+ const {
102+ encodedSparesFilter,
103+ isLoading : isLoadingSparesDefinition ,
104+ sparesDefinition,
105+ } = useSparesFilterState ( ) ;
106+
107+ const isSparesDefinitionDefined =
108+ sparesDefinition !== '' && sparesDefinition . system_types . length !== 0 ;
98109
99110 const systemIdSet = new Set < string > (
100111 itemsData ?. map ( ( item ) => item . system_id ) ?? [ ]
@@ -142,8 +153,6 @@ export function ItemsTable(props: ItemTableProps) {
142153 'create' | 'duplicate' | 'edit'
143154 > ( 'create' ) ;
144155
145- // Breadcrumbs + Mui table V2 + extra
146- const tableHeight = getPageHeightCalc ( '50px + 110px + 48px' ) ;
147156 const columns = React . useMemo < MRT_ColumnDef < TableRowData > [ ] > ( ( ) => {
148157 const viewCatalogueItemProperties = catalogueCategory ?. properties ?? [ ] ;
149158 const systemTypeValues = systemTypesData ?. map ( ( type ) => type . value ) ;
@@ -479,7 +488,7 @@ export function ItemsTable(props: ItemTableProps) {
479488 } ,
480489 manualFiltering : false ,
481490 paginationDisplayMode : 'pages' ,
482- positionToolbarAlertBanner : 'bottom ' ,
491+ positionToolbarAlertBanner : 'top ' ,
483492 autoResetPageIndex : false ,
484493 displayColumnDefOptions : dense
485494 ? undefined
@@ -507,10 +516,31 @@ export function ItemsTable(props: ItemTableProps) {
507516 //MRT
508517 mrtTheme,
509518 //MUI
510- muiTableContainerProps : {
511- sx : { height : dense ? '360.4px' : tableHeight } ,
512- // @ts -expect-error: MRT Table Container props does not have data-testid
513- 'data-testid' : 'items-table-container' ,
519+ muiToolbarAlertBannerProps : {
520+ sx : {
521+ '& .MuiAlert-message' : {
522+ maxWidth : undefined ,
523+ width : '100%' ,
524+ } ,
525+ } ,
526+ } ,
527+ muiTableContainerProps : ( { table } ) => {
528+ const showAlert =
529+ table . getState ( ) . showAlertBanner ||
530+ table . getFilteredSelectedRowModel ( ) . rows . length > 0 ||
531+ table . getState ( ) . grouping . length > 0 ;
532+ return {
533+ sx : {
534+ height : dense
535+ ? '360.4px'
536+ : getPageHeightCalc (
537+ // Breadcrumbs + Mui table V2 + extra
538+ `50px + 110px + 48px ${ showAlert ? '+ 54px' : '' } `
539+ ) ,
540+ flexShrink : 1 ,
541+ } ,
542+ 'data-testid' : 'items-table-container' ,
543+ } ;
514544 } ,
515545 muiTableBodyCellProps : ( { column } ) => {
516546 const disabledGroupedHeaderColumnIDs = [
@@ -606,18 +636,20 @@ export function ItemsTable(props: ItemTableProps) {
606636 >
607637 Clear Filters
608638 </ Button >
609- < Button
610- sx = { { mx : 0.5 } }
611- variant = "outlined"
612- disabled = { searchParams . get ( 'state' ) === encodedSparesFilter }
613- onClick = { ( ) => {
614- const newParams = new URLSearchParams ( searchParams ) ;
615- newParams . set ( 'state' , encodedSparesFilter ) ;
616- setSearchParams ( newParams , { replace : false } ) ;
617- } }
618- >
619- Show Spare Items
620- </ Button >
639+ { isSparesDefinitionDefined && (
640+ < Button
641+ sx = { { mx : 0.5 } }
642+ variant = "outlined"
643+ disabled = { searchParams . get ( 'state' ) === encodedSparesFilter }
644+ onClick = { ( ) => {
645+ const newParams = new URLSearchParams ( searchParams ) ;
646+ newParams . set ( 'state' , encodedSparesFilter ) ;
647+ setSearchParams ( newParams , { replace : false } ) ;
648+ } }
649+ >
650+ Show Spare Items
651+ </ Button >
652+ ) }
621653 </ Box >
622654 ) ,
623655 renderRowActionMenuItems : ( { closeMenu, row, table } ) => {
@@ -669,6 +701,51 @@ export function ItemsTable(props: ItemTableProps) {
669701 </ MenuItem > ,
670702 ] ;
671703 } ,
704+ renderToolbarAlertBannerContent :
705+ isSparesDefinitionDefined &&
706+ searchParams . get ( 'state' ) === encodedSparesFilter
707+ ? ( { table } ) => (
708+ < Grid container alignItems = "center" sx = { { px : 1 , py : 0.5 } } >
709+ < Grid size = { 2 } />
710+ < Grid size = { 8 } >
711+ < Box display = "flex" alignItems = "center" justifyContent = "center" >
712+ < Typography variant = "inherit" sx = { { pr : 1 } } >
713+ Spares Definition Filter Applied
714+ </ Typography >
715+ < Tooltip
716+ title = {
717+ sparesDefinition . system_types . length === 1
718+ ? `Items that are contained within the system type ${ sparesDefinition . system_types [ 0 ] . value } are classified as spares`
719+ : `Items that are contained within a system type of one of ${ sparesDefinition . system_types
720+ . map ( ( sys ) => sys . value )
721+ . join ( ', ' )
722+ . replace (
723+ / , ( [ ^ , ] * ) $ / ,
724+ ' or $1'
725+ ) } are classified as spares`
726+ }
727+ >
728+ < InfoOutlined fontSize = "small" />
729+ </ Tooltip >
730+ </ Box >
731+ </ Grid >
732+ < Grid size = { 2 } display = "flex" justifyContent = "flex-end" >
733+ < Tooltip title = "Clear Spares Definition Filter" >
734+ < span >
735+ < IconButton
736+ size = "small"
737+ aria-label = "Clear Spares Definition Filter"
738+ onClick = { ( ) => table . resetColumnFilters ( ) }
739+ sx = { { color : 'inherit' } }
740+ >
741+ < ClearIcon fontSize = "small" />
742+ </ IconButton >
743+ </ span >
744+ </ Tooltip >
745+ </ Grid >
746+ </ Grid >
747+ )
748+ : undefined ,
672749 renderBottomToolbarCustomActions : ( { table } ) =>
673750 displayTableRowCountText ( table , itemsData , 'Items' , {
674751 paddingLeft : '8px' ,
@@ -683,6 +760,13 @@ export function ItemsTable(props: ItemTableProps) {
683760 : undefined ,
684761 } ) ;
685762
763+ React . useEffect ( ( ) => {
764+ if ( isSparesDefinitionDefined )
765+ table . setShowAlertBanner (
766+ searchParams . get ( 'state' ) === encodedSparesFilter
767+ ) ;
768+ } , [ encodedSparesFilter , isSparesDefinitionDefined , searchParams , table ] ) ;
769+
686770 return (
687771 < div style = { { width : '100%' } } >
688772 < MaterialReactTable table = { table } />
0 commit comments