Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/common/__snapshots__/mrtTopTableAlert.component.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`MRTTopTableAlert > renders correctly 1`] = `
<body>
<div>
<div
class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation0 MuiAlert-root MuiAlert-colorInfo MuiAlert-standardInfo MuiAlert-standard css-aut081-MuiPaper-root-MuiAlert-root"
role="alert"
style="--Paper-shadow: none;"
>
<div
class="MuiAlert-message css-zioonp-MuiAlert-message"
>
<div
class="MuiGrid2-root MuiGrid2-container MuiGrid2-direction-xs-row css-3h9mfr-MuiGrid2-root"
>
<div
class="MuiGrid2-root MuiGrid2-direction-xs-row MuiGrid2-grid-xs-2 css-4t1t75-MuiGrid2-root"
/>
<div
class="MuiGrid2-root MuiGrid2-direction-xs-row MuiGrid2-grid-xs-8 css-1cdctrw-MuiGrid2-root"
>
<div
class="MuiBox-root css-gmuwbf"
>
<p
class="MuiTypography-root MuiTypography-inherit css-9uo6hb-MuiTypography-root"
>
test
</p>
<svg
aria-hidden="true"
aria-label="test"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-120dh41-MuiSvgIcon-root"
data-mui-internal-clone-element="true"
data-testid="InfoOutlinedIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8"
/>
</svg>
</div>
</div>
<div
class="MuiGrid2-root MuiGrid2-direction-xs-row MuiGrid2-grid-xs-2 css-12smr43-MuiGrid2-root"
>
<span
aria-label="Clear test filter"
class=""
data-mui-internal-clone-element="true"
>
<button
aria-label="Clear test filter"
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall css-6vo146-MuiButtonBase-root-MuiIconButton-root"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-120dh41-MuiSvgIcon-root"
data-testid="ClearIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
/>
</svg>
</button>
</span>
</div>
</div>
</div>
</div>
</div>
</body>
`;
45 changes: 45 additions & 0 deletions src/common/mrtTopTableAlert.component.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { screen } from '@testing-library/react';
import userEvent, { UserEvent } from '@testing-library/user-event';
import { act } from 'react';
import { renderComponentWithRouterProvider } from '../testUtils';
import MRTTopTableAlert, {
MRTTopTableAlertProps,
} from './mrtTopTableAlert.component';

describe('MRTTopTableAlert', () => {
let props: MRTTopTableAlertProps;
let user: UserEvent;
const clearFilters = vi.fn();

const createView = () => {
return renderComponentWithRouterProvider(<MRTTopTableAlert {...props} />);
};

beforeEach(() => {
props = {
title: 'test',
clearFilters,
clearFiltersAriaLabel: 'Clear test filter',
showInfoTooltip: true,
infoTooltipTitle: 'test',
};
user = userEvent.setup();
});

it('renders correctly', async () => {
let baseElement;
await act(async () => {
baseElement = createView().baseElement;
});
expect(baseElement).toMatchSnapshot();
});

it('call the clear filters function when the clear filter button is clicked', async () => {
createView();
await user.click(
await screen.findByRole('button', { name: 'Clear test filter' })
);

expect(clearFilters).toBeCalled();
});
});
84 changes: 84 additions & 0 deletions src/common/mrtTopTableAlert.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { InfoOutlined } from '@mui/icons-material';
import ClearIcon from '@mui/icons-material/Clear';
import {
Alert,
AlertProps,
Box,
IconButton,
Tooltip,
Typography,
} from '@mui/material';
import Grid from '@mui/material/Grid2';

export interface MRTTopTableAlertProps {
title: string;
clearFilters: () => void;
clearFiltersAriaLabel: string;
alertProps?: AlertProps;
showInfoTooltip?: boolean;
infoTooltipTitle?: React.ReactNode;
}

const MRTTopTableAlert = (props: MRTTopTableAlertProps) => {
const {
title,
clearFilters,
clearFiltersAriaLabel,
alertProps,
showInfoTooltip,
infoTooltipTitle,
} = props;
return (
<Alert
color="info"
icon={false}
sx={() => ({
'& .MuiAlert-message': {
width: '100%',
},
borderRadius: 0,
fontSize: '1rem',
left: 0,
p: 0,
position: 'relative',
right: 0,
top: 0,
width: '100%',
zIndex: 2,
})}
{...alertProps}
>
<Grid container alignItems="center" sx={{ px: 1, py: 0.5 }}>
<Grid size={2} />
<Grid size={8}>
<Box display="flex" alignItems="center" justifyContent="center">
<Typography variant="inherit" sx={{ pr: 1 }}>
{title}
</Typography>
{showInfoTooltip && (
<Tooltip title={infoTooltipTitle}>
<InfoOutlined fontSize="small" />
</Tooltip>
)}
</Box>
</Grid>
<Grid size={2} display="flex" justifyContent="flex-end">
<Tooltip title={clearFiltersAriaLabel}>
<span>
<IconButton
size="small"
aria-label={clearFiltersAriaLabel}
onClick={() => clearFilters()}
sx={{ color: 'inherit' }}
>
<ClearIcon fontSize="small" />
</IconButton>
</span>
</Tooltip>
</Grid>
</Grid>
</Alert>
);
};

export default MRTTopTableAlert;
79 changes: 15 additions & 64 deletions src/items/itemsTable.component.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import { InfoOutlined } from '@mui/icons-material';
import AddIcon from '@mui/icons-material/Add';
import ClearIcon from '@mui/icons-material/Clear';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import SaveAsIcon from '@mui/icons-material/SaveAs';
import {
Alert,
Box,
Button,
IconButton,
ListItemIcon,
ListItemText,
MenuItem,
Link as MuiLink,
TableCellBaseProps,
Tooltip,
Typography,
} from '@mui/material';
import Grid from '@mui/material/Grid2';
import {
MaterialReactTable,
useMaterialReactTable,
Expand All @@ -38,6 +32,7 @@ import { useGetUsageStatuses } from '../api/usageStatuses';
import { APISettingsContext } from '../apiConfigProvider.component';
import type { SystemTableType } from '../app.types';
import { findPropertyValue } from '../catalogue/items/catalogueItemsTable.component';
import MRTTopTableAlert from '../common/mrtTopTableAlert.component';
import { usePreservedTableState } from '../common/preservedTableState.component';
import {
COLUMN_FILTER_BOOLEAN_OPTIONS,
Expand Down Expand Up @@ -731,64 +726,20 @@ export function ItemsTable(props: ItemTableProps) {
{isSparesDefinitionDefined &&
sparesDefinition &&
isSparesFilterApplied && (
<Alert
color="info"
icon={false}
sx={() => ({
'& .MuiAlert-message': {
width: '100%',
},
borderRadius: 0,
fontSize: '1rem',
left: 0,
p: 0,
position: 'relative',
right: 0,
top: 0,
width: '100%',
zIndex: 2,
})}
>
<Grid container alignItems="center" sx={{ px: 1, py: 0.5 }}>
<Grid size={2} />
<Grid size={8}>
<Box display="flex" alignItems="center" justifyContent="center">
<Typography variant="inherit" sx={{ pr: 1 }}>
Spares Definition Filter Applied
</Typography>
<Tooltip
title={
sparesDefinition.system_types.length === 1
? `Items that are contained within the system type ${sparesDefinition.system_types[0].value} are classified as spares`
: `Items that are contained within a system type of one of ${sparesDefinition.system_types
.map((sys) => sys.value)
.join(', ')
.replace(
/, ([^,]*)$/,
' or $1'
)} are classified as spares`
}
>
<InfoOutlined fontSize="small" />
</Tooltip>
</Box>
</Grid>
<Grid size={2} display="flex" justifyContent="flex-end">
<Tooltip title="Clear Spares Definition Filter">
<span>
<IconButton
size="small"
aria-label="Clear Spares Definition Filter"
onClick={() => table.resetColumnFilters()}
sx={{ color: 'inherit' }}
>
<ClearIcon fontSize="small" />
</IconButton>
</span>
</Tooltip>
</Grid>
</Grid>
</Alert>
<MRTTopTableAlert
title="Spares Definition Filter Applied"
clearFilters={table.resetColumnFilters}
clearFiltersAriaLabel="Clear Spares Definition Filter"
showInfoTooltip
infoTooltipTitle={
sparesDefinition.system_types.length === 1
? `Items that are contained within the system type ${sparesDefinition.system_types[0].value} are classified as spares`
: `Items that are contained within a system type of one of ${sparesDefinition.system_types
.map((sys) => sys.value)
.join(', ')
.replace(/, ([^,]*)$/, ' or $1')} are classified as spares`
}
/>
)}
<MaterialReactTable table={table} />
{!dense && selectedItem && (
Expand Down