Se agrega persistencia en tab de datos y mapa curricular

fix #42
fix #54
This commit is contained in:
2026-02-03 16:05:05 -06:00
parent 64d9aa336f
commit 261dec7fa9
4 changed files with 171 additions and 37 deletions

View File

@@ -165,7 +165,7 @@ export async function plan_asignaturas_list(
const { data, error } = await supabase
.from('asignaturas')
.select(
'id,plan_estudio_id,estructura_id,facultad_propietaria_id,codigo,nombre,tipo,creditos,horas_semana,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en',
'id,plan_estudio_id,horas_academicas, horas_independientes,estructura_id,codigo,nombre,tipo,creditos,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en',
)
.eq('plan_estudio_id', planId)
.order('numero_ciclo', { ascending: true, nullsFirst: false })

View File

@@ -1,6 +1,9 @@
import { supabaseBrowser } from '../supabase/client'
import { invokeEdge } from '../supabase/invokeEdge'
import { throwIfError, requireData } from './_helpers'
import type { DocumentoResult } from './plans.api'
import type {
Asignatura,
BibliografiaAsignatura,
@@ -8,7 +11,6 @@ import type {
TipoAsignatura,
UUID,
} from '../types/domain'
import type { DocumentoResult } from './plans.api'
const EDGE = {
subjects_create_manual: 'subjects_create_manual',
@@ -32,7 +34,7 @@ export async function subjects_get(subjectId: UUID): Promise<Asignatura> {
.from('asignaturas')
.select(
`
id,plan_estudio_id,estructura_id,facultad_propietaria_id,codigo,nombre,tipo,creditos,horas_semana,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en,
id,plan_estudio_id,estructura_id,codigo,nombre,tipo,creditos,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en,
planes_estudio(
id,carrera_id,estructura_id,nombre,nivel,tipo_ciclo,numero_ciclos,datos,estado_actual_id,activo,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en,
carreras(id,facultad_id,nombre,nombre_corto,clave_sep,activa, facultades(id,nombre,nombre_corto,color,icono))
@@ -49,7 +51,7 @@ export async function subjects_get(subjectId: UUID): Promise<Asignatura> {
export async function subjects_history(
subjectId: UUID,
): Promise<CambioAsignatura[]> {
): Promise<Array<CambioAsignatura>> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('cambios_asignatura')
@@ -65,7 +67,7 @@ export async function subjects_history(
export async function subjects_bibliografia_list(
subjectId: UUID,
): Promise<BibliografiaAsignatura[]> {
): Promise<Array<BibliografiaAsignatura>> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('bibliografia_asignatura')
@@ -112,9 +114,9 @@ export async function ai_generate_subject(payload: {
iaConfig: {
descripcionEnfoque: string
notasAdicionales?: string
archivosExistentesIds?: UUID[]
repositoriosIds?: UUID[]
archivosAdhocIds?: UUID[]
archivosExistentesIds?: Array<UUID>
repositoriosIds?: Array<UUID>
archivosAdhocIds?: Array<UUID>
usarMCP?: boolean
}
}): Promise<any> {
@@ -145,7 +147,7 @@ export async function subjects_clone_from_existing(payload: {
export async function subjects_import_from_file(payload: {
planId: UUID
archivoWordAsignaturaId: UUID
archivosAdicionalesIds?: UUID[]
archivosAdicionalesIds?: Array<UUID>
}): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_import_from_file, payload)
}
@@ -175,7 +177,7 @@ export async function subjects_update_fields(
export async function subjects_update_contenido(
subjectId: UUID,
unidades: any[],
unidades: Array<any>,
): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_update_contenido, {
subjectId,
@@ -224,3 +226,20 @@ export async function subjects_get_document(
subjectId,
})
}
export async function asignaturas_update(
asignaturaId: UUID,
patch: Partial<Asignatura>, // O tu tipo específico para el Patch de materias
): Promise<Asignatura> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('asignaturas')
.update(patch)
.eq('id', asignaturaId)
.select() // Trae la materia actualizada
.single()
throwIfError(error)
return requireData(data, 'No se pudo actualizar la asignatura.')
}

View File

@@ -1,13 +1,8 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { qk } from '../query/keys'
import type { UUID } from '../types/domain'
import type {
BibliografiaUpsertInput,
SubjectsCreateManualInput,
SubjectsUpdateFieldsPatch,
} from '../api/subjects.api'
import {
ai_generate_subject,
asignaturas_update,
subjects_bibliografia_list,
subjects_clone_from_existing,
subjects_create_manual,
@@ -21,6 +16,14 @@ import {
subjects_update_contenido,
subjects_update_fields,
} from '../api/subjects.api'
import { qk } from '../query/keys'
import type {
BibliografiaUpsertInput,
SubjectsCreateManualInput,
SubjectsUpdateFieldsPatch,
} from '../api/subjects.api'
import type { UUID } from '../types/domain'
export function useSubject(subjectId: UUID | null | undefined) {
return useQuery({
@@ -159,7 +162,7 @@ export function useUpdateSubjectContenido() {
const qc = useQueryClient()
return useMutation({
mutationFn: (vars: { subjectId: UUID; unidades: any[] }) =>
mutationFn: (vars: { subjectId: UUID; unidades: Array<any> }) =>
subjects_update_contenido(vars.subjectId, vars.unidades),
onSuccess: (updated) => {
qc.setQueryData(qk.asignatura(updated.id), updated)
@@ -194,3 +197,28 @@ export function useGenerateSubjectDocumento() {
},
})
}
export function useUpdateAsignatura() {
const qc = useQueryClient()
return useMutation({
mutationFn: (vars: {
asignaturaId: UUID
patch: Partial<SubjectsUpdateFieldsPatch>
}) => asignaturas_update(vars.asignaturaId, vars.patch),
onSuccess: (updated) => {
// 1. Actualizamos la materia específica en la caché si tienes un query de "detalle"
qc.setQueryData(['asignatura', updated.id], updated)
// 2. IMPORTANTÍSIMO: Invalidamos la lista de materias del plan
// para que el mapa curricular vea los cambios (créditos, horas, nombre, etc.)
qc.invalidateQueries({
queryKey: ['plan_asignaturas', updated.plan_estudio_id],
})
// 3. Si tienes una lista general de asignaturas, también la invalidamos
qc.invalidateQueries({ queryKey: ['asignaturas', 'list'] })
},
})
}