When the first column hovers over the combobox it starts to flicker, when I scroll past the checkboxes it disappears completely.
I’ve tried style changes but that doesn’t help, I’ve searched on the internet, I haven’t found anything either. GPT chat doesn’t help either.
What can be done about this?
I have table in react:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { DataGrid, GridActionsCellItem } from '@mui/x-data-grid';
import { Button, TextField, Dialog, DialogActions, DialogContent, DialogTitle, Checkbox, Box, MenuItem, Select } from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import { saveAs } from 'file-saver';
import { tableStyles, columnModel } from './TableStyle'; // Import stylów
const Table = () => {
const [data, setData] = useState([]);
const [newRow, setNewRow] = useState({
nazwa: '',
comments: '',
weight: '',
type: '',
t: false,
});
const [open, setOpen] = useState(false);
useEffect(() => {
const fetchData = async () => {
try {
const token = localStorage.getItem('token');
const response = await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'fetch',
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const fetchedData = response.data.map((row, index) => ({
id: row.id || index, // Ensure each row has a unique id
...row,
}));
setData(fetchedData);
} catch (err) {
console.error('Error fetching data', err);
}
};
fetchData();
}, []);
const handleEditCellChange = async (newRow) => {
const updatedRow = data.find((row) => row.id === newRow.id);
if (updatedRow) {
try {
const token = localStorage.getItem('token');
await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'update',
id: newRow.id,
data: newRow,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setData(data.map(row => (row.id === newRow.id ? newRow : row)));
} catch (err) {
console.error('Error updating data', err);
}
}
return newRow;
};
const handleToggleCheckbox = async (id, field, value) => {
const updatedRow = data.find((row) => row.id === id);
if (updatedRow) {
const updatedData = { ...updatedRow, [field]: value };
try {
const token = localStorage.getItem('token');
await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'update',
id,
data: updatedData,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setData(data.map(row => (row.id === id ? updatedData : row)));
} catch (err) {
console.error('Error updating data', err);
}
}
};
const handleSelectChange = async (id, field, value) => {
const updatedRow = data.find((row) => row.id === id);
if (updatedRow) {
const updatedData = { ...updatedRow, [field]: value };
try {
const token = localStorage.getItem('token');
await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'update',
id,
data: updatedData,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setData(data.map(row => (row.id === id ? updatedData : row)));
} catch (err) {
console.error('Error updating data', err);
}
}
};
const handleAddRowChange = (e) => {
const { name, value, type, checked } = e.target;
setNewRow({
...newRow,
[name]: type === 'checkbox' ? checked : value,
});
};
const handleAddRow = async () => {
try {
const token = localStorage.getItem('token');
const response = await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'add',
data: newRow,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setData([...data, { ...newRow, id: response.data.id || data.length }]);
setNewRow({
nazwa: '',
comments: '',
weight: '',
type: '',
t: false,
});
setOpen(false);
} catch (err) {
console.error('Error adding row', err);
}
};
const handleDeleteRow = async (id) => {
try {
const token = localStorage.getItem('token');
await axios.post(`${process.env.REACT_APP_API_URL}/database`, {
operation: 'delete',
id,
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setData(data.filter(row => row.id !== id));
} catch (err) {
console.error('Error deleting data', err);
}
};
const handleDownloadExcel = async () => {
try {
const token = localStorage.getItem('token');
const response = await axios.post(`${process.env.REACT_APP_API_URL}/save-excel`, data, {
headers: {
Authorization: `Bearer ${token}`,
},
responseType: 'blob',
});
const blob = new Blob([response.data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
saveAs(blob, 'data.xlsx');
} catch (err) {
console.error('Error downloading Excel file', err);
alert(`Error downloading Excel file: ${err.message}`);
}
};
const getStageOptions = (type) => {
switch (type) {
case 'SZK':
return ['H', 'U', 'S', 'US', 'C', 'CS', 'G', 'D', 'E'];
case 'TAN':
return ['300', '250', '200', '150', 'GRAT'];
case 'ŚK':
return ['40', '30', '25', 'GRAT', 'MY'];
default:
return [];
}
};
const renderStageCell = (params) => {
const options = getStageOptions(params.row.type);
return (
<Box>
<Select
value={params.value || ''}
onChange={(event) => handleSelectChange(params.id, params.field, event.target.value)}
fullWidth
>
{options.map((option) => (
<MenuItem key={option} value={option}>{option}</MenuItem>
))}
</Select>
</Box>
);
};
const columns = [
{
field: 'nazwa',
headerName: 'Nazwa',
width: 200,
editable: true,
cellClassName: 'MuiDataGrid-cell--stickyLeft', // Klasa dla zablokowanej kolumny
headerClassName: 'MuiDataGrid-columnHeader--stickyLeft', // Klasa dla nagłówka zablokowanej kolumny
},
{ field: 'comments', headerName: 'Comments', width: 120, editable: true },
{ field: 'weight', headerName: 'Weight', width: 80, editable: true },
{
field: 'type',
headerName: 'Type',
width: 90,
editable: false,
renderCell: (params) => (
<Box>
<Select
value={params.value}
onChange={(event) => handleSelectChange(params.id, 'type', event.target.value)}
fullWidth
>
<MenuItem value="SZK">SZK</MenuItem>
<MenuItem value="TAN">TAN</MenuItem>
<MenuItem value="ŚK">ŚK</MenuItem>
</Select>
</Box>
)
},
{
field: 't',
headerName: 'T',
width: 50,
editable: false,
type: 'boolean',
renderCell: (params) => (
<Box>
<Checkbox
checked={Boolean(params.value)}
onChange={(event) => handleToggleCheckbox(params.id, params.field, event.target.checked)}
/>
</Box>
)
},
...Array.from({ length: 20 }, (_, i) => ({ field: `stage1_${i + 1}`, headerName: `${i + 1}`, width: 90, editable: true, renderCell: renderStageCell })),
...Array.from({ length: 15 }, (_, i) => ({ field: `stage2_${i + 1}`, headerName: `${i + 1}`, width: 90, editable: true, renderCell: renderStageCell })),
{
field: 'actions',
type: 'actions',
width: 100,
getActions: (params) => [
<GridActionsCellItem
icon={<DeleteIcon />}
label="Delete"
onClick={() => handleDeleteRow(params.id)}
/>
]
}
];
return (
<div style={{ height: '100%', width: '100%' }}>
<Box sx={{ height: '100%', width: '100%' }}>
<DataGrid
rows={data}
columns={columns}
processRowUpdate={handleEditCellChange}
columnGroupingModel={columnModel}
sx={tableStyles.root} // Użycie stylów z osobnego pliku
pinnedColumns={{ left: ['nazwa'] }} // Przypięcie pierwszej kolumny do lewej strony
/>
</Box>
<Button variant="contained" color="primary" onClick={() => setOpen(true)} style={{ marginTop: 20 }}>
Add Row
</Button>
<Button variant="contained" color="secondary" onClick={handleDownloadExcel} style={{ marginTop: 20, marginLeft: 20 }}>
Download Excel
</Button>
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>Add New Row</DialogTitle>
<DialogContent>
<TextField
autoFocus
margin="dense"
name="nazwa"
label="Nazwa"
type="text"
fullWidth
value={newRow.nazwa}
onChange={handleAddRowChange}
/>
<TextField
margin="dense"
name="comments"
label="Comments"
type="text"
fullWidth
value={newRow.comments}
onChange={handleAddRowChange}
/>
<TextField
margin="dense"
name="weight"
label="Weight"
type="text"
fullWidth
value={newRow.weight}
onChange={handleAddRowChange}
/>
<Select
name="type"
value={newRow.type}
onChange={handleAddRowChange}
fullWidth
>
<MenuItem value="SZK">SZK</MenuItem>
<MenuItem value="TAN">TAN</MenuItem>
<MenuItem value="ŚK">ŚK</MenuItem>
</Select>
<Checkbox
name="t"
checked={newRow.t}
onChange={handleAddRowChange}
/> T
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} color="primary">
Cancel
</Button>
<Button onClick={handleAddRow} color="primary">
Add
</Button>
</DialogActions>
</Dialog>
</div>
);
};
export default Table;
and style for this:
export const tableStyles = {
root: {
'& .MuiDataGrid-root': {
scrollSnapType: 'x mandatory',
},
'& .MuiDataGrid-row': {
scrollSnapAlign: 'start',
},
'& .MuiDataGrid-row:nth-of-type(odd)': {
backgroundColor: '#f5f5f5', // Alternatywne kolory wierszy
},
'& .MuiDataGrid-cell--stickyLeft': {
position: 'sticky',
left: 0,
backgroundColor: 'white',
zIndex: 1, // Zmniejszenie z-index
borderRight: '1px solid #ddd',
},
'& .MuiDataGrid-columnHeaders .MuiDataGrid-columnHeader--stickyLeft': {
position: 'sticky',
left: 0,
backgroundColor: 'white',
zIndex: 1, // Zmniejszenie z-index
borderRight: '1px solid #ddd',
},
'& .MuiDataGrid-cell:not(.MuiDataGrid-cell--stickyLeft)': {
zIndex: 0, // Ustawienie z-index: 0 dla wszystkich komórek poza pierwszą kolumną
},
'& .MuiDataGrid-cell:not(.MuiDataGrid-cell--stickyLeft) *': {
zIndex: 0, // Ustawienie z-index: 0 dla wszystkich elementów wewnątrz komórek poza pierwszą kolumną
},
'& .MuiDataGrid-columnHeaders .MuiDataGrid-columnHeader:not(.MuiDataGrid-columnHeader--stickyLeft)': {
zIndex: 0, // Ustawienie z-index: 0 dla nagłówków kolumn innych niż pierwsza
},
'& .MuiDataGrid-columnHeaders .MuiDataGrid-columnHeader:not(.MuiDataGrid-columnHeader--stickyLeft) *': {
zIndex: 0, // Ustawienie z-index: 0 dla wszystkich elementów wewnątrz nagłówków kolumn innych niż pierwsza
},
'& .MuiDataGrid-columnHeaderTitleContainer.MuiDataGrid-withBorderColor': {
zIndex: 0, // Ustawienie z-index: 0 dla obiektów o klasie MuiDataGrid-columnHeaderTitleContainer MuiDataGrid-withBorderColor
},
'& .MuiDataGrid-columnHeaderTitleContainer.MuiDataGrid-withBorderColor *': {
zIndex: 0, // Ustawienie z-index: 0 dla zawartości obiektów o klasie MuiDataGrid-columnHeaderTitleContainer MuiDataGrid-withBorderColor
},
},
};