feat: adicionar exibição da fase da OF no histórico de apontamentos
This commit is contained in:
@@ -12,12 +12,15 @@ import { ptBR } from 'date-fns/locale';
|
||||
export const ApontamentosList = () => {
|
||||
const { apontamentos, loading } = useApontamentosProducao();
|
||||
const [filtroOF, setFiltroOF] = useState('');
|
||||
const [filtroFase, setFiltroFase] = useState('');
|
||||
const [filtroProcesso, setFiltroProcesso] = useState('');
|
||||
const [filtroData, setFiltroData] = useState('');
|
||||
const [filtroPecaComponente, setFiltroPecaComponente] = useState('');
|
||||
|
||||
const apontamentosFiltrados = apontamentos.filter(apt => {
|
||||
const matchOF = !filtroOF || apt.of_number.toLowerCase().includes(filtroOF.toLowerCase());
|
||||
const faseStr = apt.peca?.etapa_fase || (apt.componente as any)?.peca?.etapa_fase || '';
|
||||
const matchFase = !filtroFase || faseStr.toLowerCase().includes(filtroFase.toLowerCase());
|
||||
const matchProcesso = !filtroProcesso || apt.processo?.nome.toLowerCase().includes(filtroProcesso.toLowerCase());
|
||||
const matchData = !filtroData || apt.data_apontamento.includes(filtroData);
|
||||
|
||||
@@ -25,7 +28,7 @@ export const ApontamentosList = () => {
|
||||
const matchPecaComponente = !filtroPecaComponente ||
|
||||
getMarcaExibida(apt).toLowerCase().includes(filtroPecaComponente.toLowerCase());
|
||||
|
||||
return matchOF && matchProcesso && matchData && matchPecaComponente;
|
||||
return matchOF && matchFase && matchProcesso && matchData && matchPecaComponente;
|
||||
});
|
||||
|
||||
// Função para determinar a marca exibida baseada no tipo de apontamento
|
||||
@@ -90,7 +93,7 @@ export const ApontamentosList = () => {
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 md:grid-cols-5 gap-3">
|
||||
<div className="grid grid-cols-1 md:grid-cols-6 gap-3">
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">OF</label>
|
||||
<Input
|
||||
@@ -100,6 +103,15 @@ export const ApontamentosList = () => {
|
||||
className="h-8"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">Fase</label>
|
||||
<Input
|
||||
placeholder="Filtrar por fase..."
|
||||
value={filtroFase}
|
||||
onChange={(e) => setFiltroFase(e.target.value)}
|
||||
className="h-8"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">Processo</label>
|
||||
<Input
|
||||
@@ -163,6 +175,7 @@ export const ApontamentosList = () => {
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>OF</TableHead>
|
||||
<TableHead>Fase</TableHead>
|
||||
<TableHead>Peça/Componente</TableHead>
|
||||
<TableHead>Tipo</TableHead>
|
||||
<TableHead>Processo</TableHead>
|
||||
@@ -184,6 +197,17 @@ export const ApontamentosList = () => {
|
||||
<TableCell className="font-medium py-1">
|
||||
{apontamento.of_number}
|
||||
</TableCell>
|
||||
<TableCell className="py-1">
|
||||
{apontamento.peca?.etapa_fase ? (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{apontamento.peca.etapa_fase.toLowerCase().startsWith('fase') || apontamento.peca.etapa_fase.toLowerCase().startsWith('etapa')
|
||||
? apontamento.peca.etapa_fase
|
||||
: `Fase ${apontamento.peca.etapa_fase}`}
|
||||
</Badge>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">-</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="py-1">
|
||||
<div className="font-medium">
|
||||
{getMarcaExibida(apontamento)}
|
||||
|
||||
@@ -95,7 +95,9 @@ export const ApontamentosFilters: React.FC<ApontamentosFiltersProps> = ({
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Todas as fases</SelectItem>
|
||||
{uniqueFases.map((fase) => (
|
||||
<SelectItem key={fase} value={fase}>{fase}</SelectItem>
|
||||
<SelectItem key={fase} value={fase}>
|
||||
{fase.toLowerCase().startsWith('fase') || fase.toLowerCase().startsWith('etapa') ? fase : `Fase ${fase}`}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -35,6 +35,15 @@ export const ApontamentosListItem: React.FC<ApontamentosListItemProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const getFaseItem = (apontamento: ApontamentoProducao) => {
|
||||
const rawFase = apontamento.peca?.etapa_fase || (apontamento.componente as any)?.peca?.etapa_fase;
|
||||
if (!rawFase || !String(rawFase).trim()) return null;
|
||||
const str = String(rawFase).trim();
|
||||
return str.toLowerCase().startsWith('fase') || str.toLowerCase().startsWith('etapa')
|
||||
? str
|
||||
: `Fase ${str}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between p-3 border rounded-lg hover:bg-muted/50 transition-colors">
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -52,6 +61,21 @@ export const ApontamentosListItem: React.FC<ApontamentosListItemProps> = ({
|
||||
<Badge variant="outline">
|
||||
{apontamento.of_number || 'N/A'}
|
||||
</Badge>
|
||||
{getFaseItem(apontamento) ? (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="bg-sky-50 text-sky-700 border-sky-200 dark:bg-sky-950/60 dark:text-sky-300 dark:border-sky-800 text-xs font-semibold"
|
||||
>
|
||||
{getFaseItem(apontamento)}
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="text-muted-foreground border-dashed text-xs"
|
||||
>
|
||||
Fase -
|
||||
</Badge>
|
||||
)}
|
||||
{apontamento.is_forcado && (
|
||||
<span className={`text-[10px] font-black px-2 py-0.5 rounded-full border ${
|
||||
apontamento.status_confirmacao === 'pendente_confirmacao'
|
||||
@@ -100,7 +124,7 @@ export const ApontamentosListItem: React.FC<ApontamentosListItemProps> = ({
|
||||
Tem certeza de que deseja reverter este apontamento?
|
||||
Esta ação não pode ser desfeita e irá remover permanentemente o registro de:
|
||||
<br />
|
||||
<strong>{getMarcaItem(apontamento)}</strong> - {apontamento.quantidade_produzida} unidades
|
||||
<strong>{getMarcaItem(apontamento)}</strong> (OF: {apontamento.of_number || 'N/A'}{getFaseItem(apontamento) ? ` • ${getFaseItem(apontamento)}` : ''}) - {apontamento.quantidade_produzida} unidades
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
|
||||
@@ -89,12 +89,12 @@ export const useApontamentosFilters = (apontamentos: ApontamentoProducao[]) => {
|
||||
: apontamentos;
|
||||
|
||||
const fases = apontamentosFiltrados
|
||||
.map(apt => apt.peca?.etapa_fase)
|
||||
.map(apt => apt.peca?.etapa_fase || (apt.componente as any)?.peca?.etapa_fase)
|
||||
.filter((fase): fase is string => {
|
||||
return typeof fase === 'string' && fase.trim() !== '';
|
||||
})
|
||||
.filter((fase, index, array) => array.indexOf(fase) === index)
|
||||
.sort();
|
||||
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));
|
||||
|
||||
console.log(`📋 Fases únicas encontradas para OF "${filterOF}": ${fases.length}`, fases);
|
||||
return fases;
|
||||
@@ -166,7 +166,7 @@ export const useApontamentosFilters = (apontamentos: ApontamentoProducao[]) => {
|
||||
// Aplicar filtro por Fase APENAS se selecionado
|
||||
if (filterFase && filterFase !== '' && filterFase !== 'all') {
|
||||
const beforeFase = resultado.length;
|
||||
resultado = resultado.filter(apt => apt.peca?.etapa_fase === filterFase);
|
||||
resultado = resultado.filter(apt => (apt.peca?.etapa_fase || (apt.componente as any)?.peca?.etapa_fase) === filterFase);
|
||||
console.log(`📋 Filtro Fase "${filterFase}": ${beforeFase} → ${resultado.length} registros`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user