125 lines
7.1 KiB
TypeScript
125 lines
7.1 KiB
TypeScript
import React from 'react';
|
|
import { Box, Typography, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Slider, Checkbox } from '@mui/material';
|
|
import { useFeedStore } from '../../store/feedStore';
|
|
|
|
export const AnomalyTable: React.FC = () => {
|
|
const { tabs, selectedTabIndex, updateTab } = useFeedStore();
|
|
|
|
if (tabs.length === 0 || selectedTabIndex < 0) {
|
|
return <Typography sx={{ p: 2 }}>Loading feeds...</Typography>;
|
|
}
|
|
|
|
const activeTab = tabs[selectedTabIndex];
|
|
const anomalies = activeTab.anomalies || [];
|
|
|
|
if (anomalies.length === 0) {
|
|
return (
|
|
<Box sx={{ p: 4, textAlign: 'center' }}>
|
|
<Typography variant="body1" color="textSecondary">
|
|
No anomalies found for the selected criteria.
|
|
</Typography>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
const handleRowClick = (index: number) => {
|
|
updateTab(selectedTabIndex, { selectedAnomalyIndex: index });
|
|
};
|
|
|
|
const getRowColor = (index: number, _asset: string) => {
|
|
// Dark mode colors for table rows
|
|
const colors = ['rgba(255, 255, 255, 0.03)', 'rgba(255, 255, 255, 0.0)'];
|
|
return colors[index % colors.length];
|
|
};
|
|
|
|
return (
|
|
<TableContainer component={Paper} sx={{ borderRadius: 0, boxShadow: 'none', height: 'calc(100vh - 180px)', bgcolor: 'transparent' }}>
|
|
<Table stickyHeader size="small" sx={{ minWidth: 1200 }}>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>#ID</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>PLAZA</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>ROAD</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>DATE</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>CHAINAGE</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>LAT/LONG</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>ANOMALY</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>SIDE</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>ANOMALY True/False</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>FEATURES</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>COMMENTS</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>CHECKED</TableCell>
|
|
<TableCell sx={{ fontWeight: 'bold', bgcolor: 'background.paper', color: 'text.primary', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>AUTO AUDIT</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{anomalies.map((anomaly: any, index: number) => {
|
|
const isSelected = activeTab.selectedAnomalyIndex === index;
|
|
const assetName = anomaly?.Asset?.replace(/_/gi, ' ') || 'Unknown Asset';
|
|
const rowColor = getRowColor(index, assetName);
|
|
|
|
// Parse Position
|
|
let latStr = 'N/A';
|
|
let longStr = 'E/A';
|
|
if (anomaly?.Pos) {
|
|
const match = String(anomaly.Pos).match(/([NS][0-9.]+)([EW][0-9.]+)/i);
|
|
if (match) {
|
|
latStr = match[1];
|
|
longStr = match[2];
|
|
} else {
|
|
latStr = anomaly.Pos; // Fallback
|
|
longStr = '';
|
|
}
|
|
}
|
|
|
|
return (
|
|
<TableRow
|
|
key={anomaly._id || index}
|
|
onClick={() => handleRowClick(index)}
|
|
sx={{
|
|
bgcolor: isSelected ? 'rgba(59, 130, 246, 0.2)' : rowColor,
|
|
cursor: 'pointer',
|
|
'&:hover': { bgcolor: 'rgba(255,255,255,0.08)' },
|
|
borderLeft: isSelected ? '4px solid #3b82f6' : '4px solid transparent',
|
|
mb: 1,
|
|
}}
|
|
>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>#{anomaly.id || anomaly._id?.substring(0, 7) || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Plaza || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.road || anomaly.Road || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Created_on ? new Date(anomaly.Created_on).toLocaleDateString() : 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Chainage || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)', fontSize: '0.75rem' }}>
|
|
{latStr}<br/>
|
|
{longStr}
|
|
</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{assetName}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Side || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)', width: 120 }}>
|
|
<Slider
|
|
size="small"
|
|
value={anomaly.Audit_status || anomaly.anomaly_status_slider || 50}
|
|
step={100}
|
|
marks
|
|
min={0}
|
|
max={100}
|
|
sx={{ color: '#ff4d4f' }}
|
|
/>
|
|
</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Features || 'N/A'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>{anomaly.Comments || '-'}</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
|
|
<Checkbox size="small" checked={!!anomaly.IsAudited} />
|
|
</TableCell>
|
|
<TableCell sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
|
|
<Checkbox size="small" checked={!!anomaly.auto_audit} />
|
|
</TableCell>
|
|
</TableRow>
|
|
);
|
|
})}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
);
|
|
};
|