Files
ETB/ETB-FrontEnd/src/pages/ProblemManagement/RootCauseAnalysis.tsx
Iliyan Angelov 306b20e24a Frontend start
2025-09-14 00:54:48 +03:00

384 lines
13 KiB
TypeScript

import React, { useState } from 'react';
import {
Grid,
Paper,
Typography,
Box,
Card,
CardContent,
Button,
Chip,
TextField,
List,
ListItem,
ListItemText,
ListItemIcon,
Divider,
Alert,
Stepper,
Step,
StepLabel,
StepContent,
Accordion,
AccordionSummary,
AccordionDetails,
} from '@mui/material';
import {
Build,
Search,
Timeline,
CheckCircle,
Cancel,
ExpandMore,
Add,
} from '@mui/icons-material';
const analysisMethods = [
{
id: '5why',
name: '5 Whys Analysis',
description: 'Ask "why" five times to drill down to the root cause',
icon: <Search />,
},
{
id: 'fishbone',
name: 'Fishbone Diagram',
description: 'Categorize potential causes into main categories',
icon: <Timeline />,
},
{
id: 'pareto',
name: 'Pareto Analysis',
description: 'Identify the 20% of causes that create 80% of problems',
icon: <Build />,
},
{
id: 'fault-tree',
name: 'Fault Tree Analysis',
description: 'Systematic approach to identify all possible causes',
icon: <Timeline />,
},
];
const currentAnalysis = {
problemId: 'PRB001',
title: 'Recurring Email Server Outages',
status: 'In Progress',
method: '5why',
findings: [
{
id: 1,
question: 'Why did the email server go down?',
answer: 'The server ran out of disk space',
evidence: 'Disk usage logs show 100% utilization',
verified: true,
},
{
id: 2,
question: 'Why did the server run out of disk space?',
answer: 'Log files were not being rotated properly',
evidence: 'Log rotation script failed due to permission issues',
verified: true,
},
{
id: 3,
question: 'Why did the log rotation script fail?',
answer: 'The script was running with incorrect permissions',
evidence: 'Script was running as root but needed mail user permissions',
verified: true,
},
{
id: 4,
question: 'Why was the script running with incorrect permissions?',
answer: 'The deployment process did not set proper ownership',
evidence: 'Deployment documentation missing permission setup steps',
verified: true,
},
{
id: 5,
question: 'Why was the deployment process missing permission setup?',
answer: 'No formal deployment checklist or validation process',
evidence: 'Deployment was done manually without following procedures',
verified: true,
},
],
rootCause: 'Lack of formal deployment procedures and validation processes',
recommendations: [
'Implement formal deployment checklist',
'Add automated permission validation',
'Create deployment approval process',
'Implement monitoring for disk usage',
],
};
const RootCauseAnalysis: React.FC = () => {
const [selectedMethod, setSelectedMethod] = useState('5why');
const [newFinding, setNewFinding] = useState({
question: '',
answer: '',
evidence: '',
});
const [showAddForm, setShowAddForm] = useState<boolean>(false);
const handleAddFinding = () => {
console.log('Adding finding:', newFinding);
setNewFinding({ question: '', answer: '', evidence: '' });
setShowAddForm(false);
};
const getMethodIcon = (methodId: any) => {
const method = analysisMethods.find(m => m.id === methodId);
return method ? method.icon : <Build />;
};
return (
<Box>
<Typography variant="h4" gutterBottom>
Root Cause Analysis
</Typography>
<Typography variant="subtitle1" color="text.secondary" gutterBottom>
Systematic investigation to identify the underlying cause of problems
</Typography>
<Grid container spacing={3}>
{/* Problem Information */}
<Grid item xs={12} md={4}>
<Paper sx={{ p: 2, mb: 3 }}>
<Typography variant="h6" gutterBottom>
Problem Information
</Typography>
<Divider sx={{ mb: 2 }} />
<Typography><strong>Problem ID:</strong> {currentAnalysis.problemId}</Typography>
<Typography><strong>Title:</strong> {currentAnalysis.title}</Typography>
<Typography><strong>Status:</strong>
<Chip
label={currentAnalysis.status}
size="small"
color="warning"
sx={{ ml: 1 }}
/>
</Typography>
<Typography><strong>Method:</strong>
<Box sx={{ display: 'flex', alignItems: 'center', mt: 1 }}>
{getMethodIcon(currentAnalysis.method)}
<Typography variant="body2" sx={{ ml: 1 }}>
{analysisMethods.find(m => m.id === currentAnalysis.method)?.name}
</Typography>
</Box>
</Typography>
</Paper>
<Paper sx={{ p: 2 }}>
<Typography variant="h6" gutterBottom>
Analysis Methods
</Typography>
<Divider sx={{ mb: 2 }} />
{analysisMethods.map((method) => (
<Card
key={method.id}
sx={{
mb: 1,
cursor: 'pointer',
border: selectedMethod === method.id ? 2 : 1,
borderColor: selectedMethod === method.id ? 'primary.main' : 'divider'
}}
onClick={() => setSelectedMethod(method.id)}
>
<CardContent sx={{ p: 2, '&:last-child': { pb: 2 } }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
<Box sx={{ color: 'primary.main', mr: 1 }}>
{method.icon}
</Box>
<Typography variant="subtitle2">{method.name}</Typography>
</Box>
<Typography variant="body2" color="text.secondary">
{method.description}
</Typography>
</CardContent>
</Card>
))}
</Paper>
</Grid>
{/* Analysis Content */}
<Grid item xs={12} md={8}>
{selectedMethod === '5why' && (
<Paper sx={{ p: 2, mb: 3 }}>
<Typography variant="h6" gutterBottom>
5 Whys Analysis
</Typography>
<Divider sx={{ mb: 2 }} />
<Stepper orientation="vertical">
{currentAnalysis.findings.map((finding, index) => (
<Step key={finding.id} active>
<StepLabel>
<Typography variant="subtitle1">
Why #{index + 1}
</Typography>
</StepLabel>
<StepContent>
<Card sx={{ mb: 2 }}>
<CardContent>
<Typography variant="subtitle2" gutterBottom>
{finding.question}
</Typography>
<Typography variant="body1" sx={{ mb: 2 }}>
<strong>Answer:</strong> {finding.answer}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
<strong>Evidence:</strong> {finding.evidence}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Chip
icon={finding.verified ? <CheckCircle /> : <Cancel />}
label={finding.verified ? 'Verified' : 'Unverified'}
size="small"
color={finding.verified ? 'success' : 'error'}
/>
</Box>
</CardContent>
</Card>
</StepContent>
</Step>
))}
</Stepper>
{showAddForm && (
<Card sx={{ mt: 2, p: 2 }}>
<Typography variant="h6" gutterBottom>
Add New Finding
</Typography>
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
fullWidth
label="Question"
value={newFinding.question}
onChange={(e) => setNewFinding(prev => ({ ...prev, question: e.target.value }))}
placeholder="Why did this happen?"
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
label="Answer"
value={newFinding.answer}
onChange={(e) => setNewFinding(prev => ({ ...prev, answer: e.target.value }))}
placeholder="The answer to the question"
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
label="Evidence"
value={newFinding.evidence}
onChange={(e) => setNewFinding(prev => ({ ...prev, evidence: e.target.value }))}
placeholder="Supporting evidence or data"
/>
</Grid>
<Grid item xs={12}>
<Box sx={{ display: 'flex', gap: 1 }}>
<Button variant="contained" onClick={handleAddFinding}>
Add Finding
</Button>
<Button onClick={() => setShowAddForm(false)}>
Cancel
</Button>
</Box>
</Grid>
</Grid>
</Card>
)}
{!showAddForm && (
<Button
variant="outlined"
startIcon={<Add />}
onClick={() => setShowAddForm(true)}
sx={{ mt: 2 }}
>
Add Finding
</Button>
)}
</Paper>
)}
{/* Root Cause Summary */}
<Paper sx={{ p: 2, mb: 3 }}>
<Typography variant="h6" gutterBottom>
Root Cause Summary
</Typography>
<Divider sx={{ mb: 2 }} />
<Alert severity="info" sx={{ mb: 2 }}>
<Typography variant="subtitle2">Identified Root Cause:</Typography>
<Typography>{currentAnalysis.rootCause}</Typography>
</Alert>
<Typography variant="h6" gutterBottom>
Recommendations
</Typography>
<List>
{currentAnalysis.recommendations.map((recommendation, index) => (
<ListItem key={index}>
<ListItemIcon>
<CheckCircle color="success" />
</ListItemIcon>
<ListItemText primary={recommendation} />
</ListItem>
))}
</List>
</Paper>
{/* Action Items */}
<Paper sx={{ p: 2 }}>
<Typography variant="h6" gutterBottom>
Action Items
</Typography>
<Divider sx={{ mb: 2 }} />
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
<Typography>Implement Deployment Checklist</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Create a comprehensive deployment checklist that includes permission validation,
disk space checks, and service health verification.
</Typography>
<Box sx={{ mt: 2 }}>
<Button variant="outlined" size="small" sx={{ mr: 1 }}>
Assign
</Button>
<Button variant="outlined" size="small">
Set Due Date
</Button>
</Box>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMore />}>
<Typography>Add Disk Usage Monitoring</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
Implement automated monitoring for disk usage with alerts when usage exceeds 80%.
</Typography>
<Box sx={{ mt: 2 }}>
<Button variant="outlined" size="small" sx={{ mr: 1 }}>
Assign
</Button>
<Button variant="outlined" size="small">
Set Due Date
</Button>
</Box>
</AccordionDetails>
</Accordion>
</Paper>
</Grid>
</Grid>
</Box>
);
}
export default RootCauseAnalysis;