fix(cronograma): corrigir salvamento e atualizacao automatica da lista de cronogramas

This commit is contained in:
2026-08-21 14:32:52 +00:00
parent 2c20ae7e3c
commit f2fd8bd699
4 changed files with 88 additions and 296 deletions
+5 -1
View File
@@ -20,6 +20,7 @@ interface CronogramaFormProps {
cronograma?: CronogramaOf | null; cronograma?: CronogramaOf | null;
onClose: () => void; onClose: () => void;
isOpen: boolean; isOpen: boolean;
onSaveSuccess?: () => void;
} }
const processosDefault = [ const processosDefault = [
@@ -30,7 +31,7 @@ const processosDefault = [
'Aceite/DB' 'Aceite/DB'
]; ];
export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onClose, isOpen }) => { export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onClose, isOpen, onSaveSuccess }) => {
const { saveCronograma, getCronogramaPorOf } = useCronogramaOperations(); const { saveCronograma, getCronogramaPorOf } = useCronogramaOperations();
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
of_id: '', of_id: '',
@@ -228,6 +229,9 @@ export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onCl
setLoading(false); setLoading(false);
if (success) { if (success) {
if (onSaveSuccess) {
onSaveSuccess();
}
onClose(); onClose();
} }
}; };
+1 -249
View File
@@ -1,249 +1 @@
export { useCronogramas as useCronogramaOperations } from './useCronogramas';
import { useState, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { toast } from 'sonner';
import { useAuth } from './useAuth';
import { CronogramaOf } from '@/types/cronograma';
export const useCronogramaOperations = () => {
const { user } = useAuth();
const [cronogramas, setCronogramas] = useState<CronogramaOf[]>([]);
const [loading, setLoading] = useState(false);
const loadCronogramas = async () => {
try {
setLoading(true);
const { data: cronogramasData, error: cronogramasError } = await supabase
.from('cronogramas_of')
.select(`
*,
ordens_fabricacao (
num_of,
descritivo
),
profiles!cronogramas_of_gestor_id_fkey (
full_name,
email
)
`)
.order('created_at', { ascending: false });
if (cronogramasError) throw cronogramasError;
// Carregar processos para cada cronograma
const cronogramasComProcessos = await Promise.all(
(cronogramasData || []).map(async (cronograma) => {
const { data: processos, error: processosError } = await supabase
.from('processos_cronograma')
.select('*')
.eq('cronograma_id', cronograma.id)
.order('ordem');
if (processosError) throw processosError;
return {
id: cronograma.id,
of_id: cronograma.of_id,
gestor_id: cronograma.gestor_id,
revisao: cronograma.revisao,
processos: processos || [],
ordem_fabricacao: cronograma.ordens_fabricacao,
gestor_profile: cronograma.profiles
} as CronogramaOf;
})
);
setCronogramas(cronogramasComProcessos);
} catch (error) {
console.error('Erro ao carregar cronogramas:', error);
toast.error('Erro ao carregar cronogramas');
} finally {
setLoading(false);
}
};
const saveCronograma = async (cronograma: Partial<CronogramaOf> & { processos: any[] }) => {
try {
if (!user) throw new Error('Usuário não autenticado');
let cronogramaId: string;
if (cronograma.id) {
// Atualizar cronograma existente
const novaRevisao = cronograma.revisao ? cronograma.revisao + 1 : 1;
const { data: updatedCronograma, error: updateError } = await supabase
.from('cronogramas_of')
.update({
gestor_id: cronograma.gestor_id,
revisao: novaRevisao,
updated_at: new Date().toISOString()
})
.eq('id', cronograma.id)
.select()
.single();
if (updateError) throw updateError;
cronogramaId = updatedCronograma.id;
// Deletar processos antigos
const { error: deleteError } = await supabase
.from('processos_cronograma')
.delete()
.eq('cronograma_id', cronogramaId);
if (deleteError) throw deleteError;
} else {
// Verificar se já existe cronograma para esta OF
const { data: existingCronograma } = await supabase
.from('cronogramas_of')
.select('id, revisao')
.eq('of_id', cronograma.of_id)
.single();
if (existingCronograma) {
// Atualizar cronograma existente
const novaRevisao = existingCronograma.revisao + 1;
const { data: updatedCronograma, error: updateError } = await supabase
.from('cronogramas_of')
.update({
gestor_id: cronograma.gestor_id,
revisao: novaRevisao,
updated_at: new Date().toISOString()
})
.eq('id', existingCronograma.id)
.select()
.single();
if (updateError) throw updateError;
cronogramaId = updatedCronograma.id;
// Deletar processos antigos
const { error: deleteError } = await supabase
.from('processos_cronograma')
.delete()
.eq('cronograma_id', cronogramaId);
if (deleteError) throw deleteError;
} else {
// Criar novo cronograma
const { data: newCronograma, error: insertError } = await supabase
.from('cronogramas_of')
.insert({
of_id: cronograma.of_id,
gestor_id: cronograma.gestor_id,
revisao: 1,
created_by: user.id
})
.select()
.single();
if (insertError) throw insertError;
cronogramaId = newCronograma.id;
}
}
// Inserir novos processos
const processosParaInserir = cronograma.processos.map(processo => ({
cronograma_id: cronogramaId,
nome_processo: processo.nome_processo,
data_inicio: processo.data_inicio,
data_fim: processo.data_fim,
ordem: processo.ordem
}));
const { error: processosError } = await supabase
.from('processos_cronograma')
.insert(processosParaInserir);
if (processosError) throw processosError;
toast.success('Cronograma salvo com sucesso!');
loadCronogramas();
return true;
} catch (error) {
console.error('Erro ao salvar cronograma:', error);
toast.error('Erro ao salvar cronograma');
return false;
}
};
const deleteCronograma = async (cronogramaId: string) => {
try {
const { error } = await supabase
.from('cronogramas_of')
.delete()
.eq('id', cronogramaId);
if (error) throw error;
toast.success('Cronograma removido com sucesso!');
loadCronogramas();
return true;
} catch (error) {
console.error('Erro ao deletar cronograma:', error);
toast.error('Erro ao remover cronograma');
return false;
}
};
const getCronogramaPorOf = async (ofId: string) => {
try {
const { data: cronograma, error } = await supabase
.from('cronogramas_of')
.select(`
*,
ordens_fabricacao (
num_of,
descritivo
),
profiles!cronogramas_of_gestor_id_fkey (
full_name,
email
)
`)
.eq('of_id', ofId)
.single();
if (error && error.code !== 'PGRST116') throw error;
if (!cronograma) return null;
const { data: processos, error: processosError } = await supabase
.from('processos_cronograma')
.select('*')
.eq('cronograma_id', cronograma.id)
.order('ordem');
if (processosError) throw processosError;
return {
id: cronograma.id,
of_id: cronograma.of_id,
gestor_id: cronograma.gestor_id,
revisao: cronograma.revisao,
processos: processos || [],
ordem_fabricacao: cronograma.ordens_fabricacao,
gestor_profile: cronograma.profiles
} as CronogramaOf;
} catch (error) {
console.error('Erro ao buscar cronograma:', error);
return null;
}
};
useEffect(() => {
loadCronogramas();
}, []);
return {
cronogramas,
loading,
loadCronogramas,
saveCronograma,
deleteCronograma,
getCronogramaPorOf
};
};
+76 -46
View File
@@ -37,7 +37,7 @@ export const useCronogramas = () => {
const loadCronogramas = async () => { const loadCronogramas = async () => {
try { try {
setLoading(true); setLoading(true);
const { data: cronogramasData, error: cronogramasError } = await supabase const { data: cronogramasData, error: cronogramasError } = await supabase
.from('cronogramas_of') .from('cronogramas_of')
.select(` .select(`
@@ -47,7 +47,7 @@ export const useCronogramas = () => {
descritivo, descritivo,
peso_total peso_total
), ),
profiles!gestor_id ( profiles!cronogramas_of_gestor_id_fkey (
full_name, full_name,
email email
) )
@@ -89,24 +89,18 @@ export const useCronogramas = () => {
} }
}; };
const saveCronograma = async (cronograma: Omit<CronogramaOf, 'id'>) => { const saveCronograma = async (cronograma: Partial<CronogramaOf> & { processos: ProcessoCronograma[] }) => {
try { try {
if (!user) throw new Error('Usuário não autenticado'); if (!user) throw new Error('Usuário não autenticado');
if (!cronograma.of_id) throw new Error('Selecione uma Ordem de Fabricação');
// Verificar se já existe cronograma para esta OF if (!cronograma.gestor_id) throw new Error('Selecione o gestor responsável');
const { data: existingCronograma } = await supabase
.from('cronogramas_of')
.select('id, revisao')
.eq('of_id', cronograma.of_id)
.single();
let cronogramaId: string; let cronogramaId: string;
let novaRevisao = 1;
if (existingCronograma) { if (cronograma.id) {
// Atualizar cronograma existente // Atualizar cronograma existente por ID
novaRevisao = existingCronograma.revisao + 1; const novaRevisao = cronograma.revisao ? cronograma.revisao + 1 : 1;
const { data: updatedCronograma, error: updateError } = await supabase const { data: updatedCronograma, error: updateError } = await supabase
.from('cronogramas_of') .from('cronogramas_of')
.update({ .update({
@@ -114,7 +108,7 @@ export const useCronogramas = () => {
revisao: novaRevisao, revisao: novaRevisao,
updated_at: new Date().toISOString() updated_at: new Date().toISOString()
}) })
.eq('id', existingCronograma.id) .eq('id', cronograma.id)
.select() .select()
.single(); .single();
@@ -129,43 +123,80 @@ export const useCronogramas = () => {
if (deleteError) throw deleteError; if (deleteError) throw deleteError;
} else { } else {
// Criar novo cronograma // Verificar se já existe cronograma para esta OF (usando maybeSingle para evitar erro PGRST116)
const { data: newCronograma, error: insertError } = await supabase const { data: existingCronograma } = await supabase
.from('cronogramas_of') .from('cronogramas_of')
.insert({ .select('id, revisao')
of_id: cronograma.of_id, .eq('of_id', cronograma.of_id)
gestor_id: cronograma.gestor_id, .maybeSingle();
revisao: 1,
created_by: user.id
})
.select()
.single();
if (insertError) throw insertError; if (existingCronograma) {
cronogramaId = newCronograma.id; // Atualizar cronograma existente
const novaRevisao = (existingCronograma.revisao || 1) + 1;
const { data: updatedCronograma, error: updateError } = await supabase
.from('cronogramas_of')
.update({
gestor_id: cronograma.gestor_id,
revisao: novaRevisao,
updated_at: new Date().toISOString()
})
.eq('id', existingCronograma.id)
.select()
.single();
if (updateError) throw updateError;
cronogramaId = updatedCronograma.id;
// Deletar processos antigos
const { error: deleteError } = await supabase
.from('processos_cronograma')
.delete()
.eq('cronograma_id', cronogramaId);
if (deleteError) throw deleteError;
} else {
// Criar novo cronograma
const { data: newCronograma, error: insertError } = await supabase
.from('cronogramas_of')
.insert({
of_id: cronograma.of_id,
gestor_id: cronograma.gestor_id,
revisao: 1,
created_by: user.id
})
.select()
.single();
if (insertError) throw insertError;
cronogramaId = newCronograma.id;
}
} }
// Inserir novos processos // Inserir novos processos
const processosParaInserir = cronograma.processos.map(processo => ({ if (cronograma.processos && cronograma.processos.length > 0) {
cronograma_id: cronogramaId, const processosParaInserir = cronograma.processos.map((processo, idx) => ({
nome_processo: processo.nome_processo, cronograma_id: cronogramaId,
data_inicio: processo.data_inicio, nome_processo: processo.nome_processo,
data_fim: processo.data_fim, data_inicio: processo.data_inicio,
ordem: processo.ordem data_fim: processo.data_fim,
})); ordem: processo.ordem || idx + 1
}));
const { error: processosError } = await supabase const { error: processosError } = await supabase
.from('processos_cronograma') .from('processos_cronograma')
.insert(processosParaInserir); .insert(processosParaInserir);
if (processosError) throw processosError; if (processosError) throw processosError;
}
toast.success('Cronograma salvo com sucesso!'); toast.success('Cronograma salvo com sucesso!');
loadCronogramas(); await loadCronogramas();
return true; return true;
} catch (error) { } catch (error) {
console.error('Erro ao salvar cronograma:', error); console.error('Erro ao salvar cronograma:', error);
toast.error('Erro ao salvar cronograma'); const errMsg = error instanceof Error ? error.message : 'Erro ao salvar cronograma';
toast.error(errMsg);
return false; return false;
} }
}; };
@@ -180,7 +211,7 @@ export const useCronogramas = () => {
if (error) throw error; if (error) throw error;
toast.success('Cronograma removido com sucesso!'); toast.success('Cronograma removido com sucesso!');
loadCronogramas(); await loadCronogramas();
return true; return true;
} catch (error) { } catch (error) {
console.error('Erro ao deletar cronograma:', error); console.error('Erro ao deletar cronograma:', error);
@@ -200,16 +231,15 @@ export const useCronogramas = () => {
descritivo, descritivo,
peso_total peso_total
), ),
profiles!gestor_id ( profiles!cronogramas_of_gestor_id_fkey (
full_name, full_name,
email email
) )
`) `)
.eq('of_id', ofId) .eq('of_id', ofId)
.single(); .maybeSingle();
if (error && error.code !== 'PGRST116') throw error;
if (error) throw error;
if (!cronograma) return null; if (!cronograma) return null;
const { data: processos, error: processosError } = await supabase const { data: processos, error: processosError } = await supabase
+6
View File
@@ -68,6 +68,11 @@ const CronogramaOF = () => {
setSelectedCronograma(null); setSelectedCronograma(null);
}; };
const handleSaveSuccess = () => {
loadCronogramas();
setActiveTab('cronogramas');
};
const handleCloseGanttChart = () => { const handleCloseGanttChart = () => {
setShowGanttChart(false); setShowGanttChart(false);
setCronogramaForGantt(null); setCronogramaForGantt(null);
@@ -285,6 +290,7 @@ const CronogramaOF = () => {
cronograma={selectedCronograma} cronograma={selectedCronograma}
onClose={handleCloseCronogramaForm} onClose={handleCloseCronogramaForm}
isOpen={showCronogramaForm} isOpen={showCronogramaForm}
onSaveSuccess={handleSaveSuccess}
/> />
)} )}