Files
paad/ts/auditoría.ts
2023-08-08 17:04:21 +00:00

278 lines
9.6 KiB
TypeScript

import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
type Registro = {
carrera: string;
carrera_id: number;
comentario: null;
dia: string;
duracion: string;
duracion_id: number;
estado_supervisor_id: number;
facultad: string;
facultad_id: number;
horario_dia: number;
horario_fin: string;
horario_grupo: string;
horario_hora: string;
horario_id: number;
materia: string;
materia_id: number;
nombre: string;
periodo: string;
periodo_id: number;
profesor_clave: string;
profesor_correo: string;
profesor_grado: null;
profesor_id: number;
profesor_nombre: string;
registro_fecha: null;
registro_fecha_ideal: Date;
registro_fecha_supervisor: Date;
registro_id: number;
registro_justificada: null;
registro_retardo: null;
salon: string;
salon_id: number;
supervisor_id: number;
}
type Estado = {
color: string;
icon: string;
estado_supervisor_id: number;
}
type Facultad = {
clave_dependencia: string;
facultad_id: number;
facultad_nombre: string;
}
type Bloque_Horario = {
hora_fin: string;
hora_inicio: string;
id: number;
selected: boolean;
}
type Filter = {
type: string;
value: string;
icon: string;
field: string;
label: string;
}
const store = reactive({
loading: false,
current: {
comentario: '',
clase_vista: null,
empty: '',
},
facultades: {
data: [] as Facultad[],
async fetch() {
this.data = [] as Facultad[]
const res = await fetch('action/action_facultad.php')
this.data = await res.json()
},
},
filters: {
facultad_id: null,
fecha: null,
fecha_inicio: null,
fecha_fin: null,
profesor: null,
bloque_horario: null,
estados: [],
switchFecha: false,
switchFechas() {
$(function () {
store.filters.fecha_inicio = store.filters.fecha_fin = store.filters.fecha = null
$("#fecha, #fecha_inicio, #fecha_fin").datepicker({
minDate: -3,
maxDate: new Date(),
dateFormat: "yy-mm-dd",
showAnim: "slide",
});
const fecha = $("#fecha"), inicio = $("#fecha_inicio"), fin = $("#fecha_fin")
inicio.on("change", function () {
store.filters.fecha_inicio = inicio.val()
fin.datepicker("option", "minDate", inicio.val());
});
fin.on("change", function () {
store.filters.fecha_fin = fin.val()
inicio.datepicker("option", "maxDate", fin.val());
});
fecha.on("change", function () {
store.filters.fecha = fecha.val()
});
});
}
},
estados: {
data: [] as Estado[],
async fetch() {
this.data = [] as Estado[]
const res = await fetch('action/action_estado_supervisor.php')
this.data = await res.json()
},
getEstado(id: number): Estado {
return this.data.find((estado: Estado) => estado.estado_supervisor_id === id)
},
printEstados() {
if (store.filters.estados.length > 0)
document.querySelector('#estados')!.innerHTML = store.filters.estados.map((estado: number) =>
`<span class="mx-2 badge badge-${store.estados.getEstado(estado).estado_color}">
<i class="${store.estados.getEstado(estado).estado_icon}"></i> ${store.estados.getEstado(estado).nombre}
</span>`
).join('')
else
document.querySelector('#estados')!.innerHTML = `Todos los registros`
}
},
bloques_horario: {
data: [] as Bloque_Horario[],
async fetch() {
this.data = [] as Bloque_Horario[]
const res = await fetch('action/action_grupo_horario.php')
this.data = await res.json()
if (this.data.every((bloque: Bloque_Horario) => !bloque.selected))
this.data[0].selected = true
},
},
toggle(arr: any, element: any) {
const newArray = arr.includes(element) ? arr.filter((item: any) => item !== element) : [...arr, element]
// if all are selected, then unselect all
if (newArray.length === this.estados.data.length) return []
return newArray
},
})
declare var $: any
type Profesor = {
profesor_id: number;
profesor_nombre: string;
profesor_correo: string;
profesor_clave: string;
profesor_grado: string;
}
createApp({
store,
get clase_vista() {
return store.current.clase_vista
},
registros: {
data: [] as Registro[],
async fetch() {
this.loading = true
this.data = [] as Registro[]
const res = await fetch('action/action_auditoria.php')
this.data = await res.json()
this.loading = false
},
invertir() {
this.data = this.data.reverse()
},
mostrarComentario(registro_id: number) {
const registro = this.data.find((registro: Registro) => registro.registro_id === registro_id)
store.current.comentario = registro.comentario
$('#ver-comentario').modal('show')
},
get relevant() {
/*
facultad_id: null,
fecha: null,
fecha_inicio: null,
fecha_fin: null,
profesor: null,
asistencia: null,
estado_id: null,
if one of the filters is null, then it is not relevant
*/
const filters = Object.keys(store.filters).filter((filtro) => store.filters[filtro] || store.filters[filtro]?.length > 0)
return this.data.filter((registro: Registro) => {
return filters.every((filtro) => {
switch (filtro) {
case 'fecha':
return registro.registro_fecha_ideal === store.filters[filtro];
case 'fecha_inicio':
return registro.registro_fecha_ideal >= store.filters[filtro];
case 'fecha_fin':
return registro.registro_fecha_ideal <= store.filters[filtro];
case 'profesor':
const textoFiltro = store.filters[filtro].toLowerCase();
if (/^\([^)]+\)\s[\s\S]+$/.test(textoFiltro)) {
const clave = registro.profesor_clave.toLowerCase();
const filtroClave = textoFiltro.match(/\((.*?)\)/)?.[1];
console.log(clave, filtroClave);
return clave.includes(filtroClave);
} else {
const nombre = registro.profesor_nombre.toLowerCase();
return nombre.includes(textoFiltro);
}
case 'facultad_id':
return registro.facultad_id === store.filters[filtro];
case 'estados':
if (store.filters[filtro].length === 0) return true;
return store.filters[filtro].includes(registro.estado_supervisor_id);
case 'bloque_horario':
const bloque = store.bloques_horario.data.find((bloque: Bloque_Horario) => bloque.id === store.filters[filtro]) as Bloque_Horario;
return registro.horario_hora <= bloque.hora_fin && registro.horario_fin >= bloque.hora_inicio;
default:
return true;
}
})
})
},
async descargar() {
if (this.relevant.length === 0) return;
const res = await fetch('export/supervisor_excel.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.relevant)
});
const blob = await res.blob();
(window as any).saveAs(blob, `auditoria_${new Date().toISOString().slice(0, 10)}.xlsx`);
}
},
get profesores() {
return this.registros.data.map((registro: Registro) => (
{
profesor_id: registro.profesor_id,
profesor_nombre: registro.profesor_nombre,
profesor_correo: registro.profesor_correo,
profesor_clave: registro.profesor_clave,
profesor_grado: registro.profesor_grado,
}
)).sort((a: Profesor, b: Profesor) =>
a.profesor_nombre.localeCompare(b.profesor_nombre)
)
},
async mounted() {
await this.registros.fetch()
await store.facultades.fetch()
await store.estados.fetch()
await store.bloques_horario.fetch()
store.filters.bloque_horario = store.bloques_horario.data.find((bloque: Bloque_Horario) => bloque.selected)?.id
store.filters.switchFechas()
}
}).mount('#app')