feat: enhance absence management with new filters and reporting options, including PDF and Excel generation capabilities
This commit is contained in:
@@ -24,9 +24,11 @@
|
||||
let timestampOriginal = $state<number | null>(null);
|
||||
let timestampUTC = $state<number | null>(null);
|
||||
let intervaloRelogio: ReturnType<typeof setInterval> | null = null;
|
||||
let dataLoaded = $state(false);
|
||||
|
||||
// Carregar dados apenas uma vez quando a query retornar
|
||||
$effect(() => {
|
||||
if (configQuery?.data) {
|
||||
if (configQuery?.data && !dataLoaded) {
|
||||
servidorNTP = configQuery.data.servidorNTP || 'pool.ntp.org';
|
||||
portaNTP = configQuery.data.portaNTP || 123;
|
||||
usarServidorExterno = configQuery.data.usarServidorExterno || false;
|
||||
@@ -40,6 +42,8 @@
|
||||
offsetSegundos: configQuery.data.offsetSegundos ?? null,
|
||||
usandoServidorExterno: configQuery.data.usarServidorExterno || false
|
||||
};
|
||||
|
||||
dataLoaded = true; // Marcar como carregado para evitar sobrescrever mudanças do usuário
|
||||
}
|
||||
});
|
||||
|
||||
@@ -53,20 +57,50 @@
|
||||
timestampUTC = resultado.timestamp; // Timestamp UTC da fonte
|
||||
// Calcular o timestamp original (antes do ajuste GMT)
|
||||
timestampOriginal = timestampUTC;
|
||||
// Atualizar status de sincronização
|
||||
statusSincronizacao = {
|
||||
ultimaSincronizacao: Date.now(),
|
||||
offsetSegundos: resultado.offsetSegundos ?? null,
|
||||
usandoServidorExterno: resultado.usandoServidorExterno || false
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Se não usar servidor externo, usar tempo local do PC (igual ao relógio de ponto)
|
||||
// Se não usar servidor externo, usar tempo do PC como base UTC
|
||||
// Date.now() retorna timestamp UTC (milissegundos desde epoch)
|
||||
timestampUTC = Date.now();
|
||||
timestampOriginal = timestampUTC;
|
||||
// Atualizar status para indicar que está usando relógio do PC
|
||||
statusSincronizacao = {
|
||||
ultimaSincronizacao: Date.now(),
|
||||
offsetSegundos: null,
|
||||
usandoServidorExterno: false
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erro ao obter tempo sincronizado:', error);
|
||||
// Fallback: usar tempo local
|
||||
// Fallback: usar tempo do PC
|
||||
timestampUTC = Date.now();
|
||||
timestampOriginal = timestampUTC;
|
||||
// Atualizar status para indicar fallback
|
||||
statusSincronizacao = {
|
||||
ultimaSincronizacao: Date.now(),
|
||||
offsetSegundos: null,
|
||||
usandoServidorExterno: false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Atualizar relógio quando usarServidorExterno mudar (após carregamento inicial)
|
||||
$effect(() => {
|
||||
// Quando a opção de usar servidor externo mudar, atualizar o relógio
|
||||
// Só atualizar após os dados serem carregados para evitar atualizações desnecessárias
|
||||
if (dataLoaded) {
|
||||
// Usar usarServidorExterno como dependência reativa
|
||||
const _ = usarServidorExterno; // Forçar reatividade
|
||||
obterTempoSincronizado();
|
||||
}
|
||||
});
|
||||
|
||||
// Inicializar e atualizar relógios periodicamente
|
||||
$effect(() => {
|
||||
// Obter tempo inicial quando configuração mudar
|
||||
@@ -97,46 +131,51 @@
|
||||
// Funções para formatar os relógios
|
||||
function formatarRelogio(timestamp: number | null, ajusteGMT: number = 0): string {
|
||||
if (!timestamp) return '--:--:--';
|
||||
// Aplicar GMT offset ao timestamp
|
||||
// Quando GMT é 0, usar timestamp UTC puro e deixar toLocaleTimeString() fazer a conversão automática
|
||||
// Quando GMT ≠ 0, aplicar offset configurado ao timestamp
|
||||
let timestampAjustado: number;
|
||||
if (ajusteGMT !== 0) {
|
||||
// Aplicar offset configurado
|
||||
timestampAjustado = timestamp + ajusteGMT * 60 * 60 * 1000;
|
||||
} else {
|
||||
// Quando GMT = 0, manter timestamp UTC puro
|
||||
// O toLocaleTimeString() converterá automaticamente para o timezone local do navegador
|
||||
timestampAjustado = timestamp;
|
||||
|
||||
// Quando ajusteGMT = 0, usar UTC explícito (sem GMT)
|
||||
if (ajusteGMT === 0) {
|
||||
return new Date(timestamp).toLocaleTimeString('pt-BR', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false,
|
||||
timeZone: 'UTC' // Forçar UTC puro
|
||||
});
|
||||
}
|
||||
const data = new Date(timestampAjustado);
|
||||
return data.toLocaleTimeString('pt-BR', {
|
||||
|
||||
// Quando ajusteGMT ≠ 0, aplicar offset configurado ao timestamp UTC
|
||||
// O offset é aplicado manualmente, então usamos UTC como base para evitar conversão dupla
|
||||
const timestampAjustado = timestamp + ajusteGMT * 60 * 60 * 1000;
|
||||
return new Date(timestampAjustado).toLocaleTimeString('pt-BR', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
hour12: false,
|
||||
timeZone: 'UTC' // Usar UTC como base pois já aplicamos o offset manualmente
|
||||
});
|
||||
}
|
||||
|
||||
function formatarDataRelogio(timestamp: number | null, ajusteGMT: number = 0): string {
|
||||
if (!timestamp) return '--/--/----';
|
||||
// Aplicar GMT offset ao timestamp
|
||||
// Quando GMT é 0, usar timestamp UTC puro e deixar toLocaleDateString() fazer a conversão automática
|
||||
// Quando GMT ≠ 0, aplicar offset configurado ao timestamp
|
||||
let timestampAjustado: number;
|
||||
if (ajusteGMT !== 0) {
|
||||
// Aplicar offset configurado
|
||||
timestampAjustado = timestamp + ajusteGMT * 60 * 60 * 1000;
|
||||
} else {
|
||||
// Quando GMT = 0, manter timestamp UTC puro
|
||||
// O toLocaleDateString() converterá automaticamente para o timezone local do navegador
|
||||
timestampAjustado = timestamp;
|
||||
|
||||
// Quando ajusteGMT = 0, usar UTC explícito (sem GMT)
|
||||
if (ajusteGMT === 0) {
|
||||
return new Date(timestamp).toLocaleDateString('pt-BR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
timeZone: 'UTC' // Forçar UTC puro
|
||||
});
|
||||
}
|
||||
const data = new Date(timestampAjustado);
|
||||
return data.toLocaleDateString('pt-BR', {
|
||||
|
||||
// Quando ajusteGMT ≠ 0, aplicar offset configurado ao timestamp UTC
|
||||
// O offset é aplicado manualmente, então usamos UTC como base para evitar conversão dupla
|
||||
const timestampAjustado = timestamp + ajusteGMT * 60 * 60 * 1000;
|
||||
return new Date(timestampAjustado).toLocaleDateString('pt-BR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
year: 'numeric',
|
||||
timeZone: 'UTC' // Usar UTC como base pois já aplicamos o offset manualmente
|
||||
});
|
||||
}
|
||||
|
||||
@@ -668,3 +707,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -427,11 +427,11 @@
|
||||
onclick={() => toggleRecurso(roleId, item.recurso)}
|
||||
disabled={salvando}
|
||||
>
|
||||
<span class="text-lg font-semibold">{item.recurso}</span>
|
||||
<ChevronDown
|
||||
<span class="text-lg font-semibold">{item.recurso}</span>
|
||||
<ChevronDown
|
||||
class="h-5 w-5 transition-transform {recursoExpandido ? 'rotate-180' : ''}"
|
||||
strokeWidth={2}
|
||||
/>
|
||||
strokeWidth={2}
|
||||
/>
|
||||
</button>
|
||||
|
||||
<!-- Lista de ações (visível quando expandido) -->
|
||||
|
||||
Reference in New Issue
Block a user