Implementar seguimiento de `seleccionado` en TablaObserver.ts

master
Araozu 2021-03-27 15:35:43 -05:00
parent cc36f070b7
commit c0a0f098be
4 changed files with 157 additions and 54 deletions

View File

@ -9,7 +9,7 @@ import { Creditos } from "./Creditos"
function App() { function App() {
/// @ts-ignore /// @ts-ignore
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined const soportaBackdropFilter = document.body.style.backdropFilter !== undefined
const mostrarMensajeBackdropFilterRaw = localStorage.getItem("mensaje-backdrop-filter-oculto") === undefined const mostrarMensajeBackdropFilterRaw = !localStorage.getItem("mensaje-backdrop-filter-oculto")
const [mostrarMensajeBackdropFilter, setMostrarMensaje] = createSignal(mostrarMensajeBackdropFilterRaw) const [mostrarMensajeBackdropFilter, setMostrarMensaje] = createSignal(mostrarMensajeBackdropFilterRaw)

View File

@ -1,7 +1,7 @@
import { StyleSheet, css } from "aphrodite" import { StyleSheet, css } from "aphrodite"
import { createMemo, For, SetStateFunction } from "solid-js" import { batch, createMemo, For, produce, SetStateFunction } from "solid-js"
import { estilosGlobales } from "../Estilos" import { estilosGlobales } from "../Estilos"
import { Cursos, ListaCursosUsuario, DataProcesada } from "../types/DatosHorario" import { Cursos, ListaCursosUsuario, DataProcesada, DatosGrupo } from "../types/DatosHorario"
import { Dia, dias, horas } from "../Store" import { Dia, dias, horas } from "../Store"
import { FilaTabla } from "./Tabla/FilaTabla" import { FilaTabla } from "./Tabla/FilaTabla"
import { TablaObserver } from "./TablaObserver" import { TablaObserver } from "./TablaObserver"
@ -115,8 +115,17 @@ const procesarAnio = (data: Cursos, anio: string, version: number, setCursosUsua
esLab: false, esLab: false,
datosGrupo: grupo, datosGrupo: grupo,
fnSeleccionar: () => { fnSeleccionar: () => {
/// @ts-ignore setCursosUsuarios("cursos", Number(indiceCurso), "Teoria", produce<{ [p: string]: DatosGrupo }>((x) => {
setCursosUsuarios("cursos", indiceCurso, "Teoria", grupoStr, "seleccionado", (x) => !x) const grupoActualSeleccionado = x[grupoStr].seleccionado
if (grupoActualSeleccionado) {
x[grupoStr].seleccionado = false
} else {
for (let xKey in x) {
x[xKey].seleccionado = xKey === grupoStr
}
}
}))
}, },
}) })
} }
@ -146,8 +155,22 @@ const procesarAnio = (data: Cursos, anio: string, version: number, setCursosUsua
esLab: true, esLab: true,
datosGrupo: grupo, datosGrupo: grupo,
fnSeleccionar: () => { fnSeleccionar: () => {
/// @ts-ignore setCursosUsuarios(
setCursosUsuarios("cursos", indiceCurso, "Laboratorio", grupoStr, "seleccionado", (x) => !x) "cursos",
Number(indiceCurso),
"Laboratorio",
produce<{ [p: string]: DatosGrupo }>((x) => {
const grupoActualSeleccionado = x[grupoStr].seleccionado
if (grupoActualSeleccionado) {
x[grupoStr].seleccionado = false
} else {
for (let xKey in x) {
x[xKey].seleccionado = xKey === grupoStr
}
}
}),
)
}, },
}) })
} }

View File

@ -1,6 +1,6 @@
import { StyleSheet, css } from "aphrodite" import { StyleSheet, css } from "aphrodite"
import { estilosGlobales } from "../../Estilos" import { estilosGlobales } from "../../Estilos"
import { For, createSignal, createMemo } from "solid-js" import { For, createSignal, createMemo, createEffect } from "solid-js"
import { Dia } from "../../Store" import { Dia } from "../../Store"
import { DatosGrupo } from "../../types/DatosHorario" import { DatosGrupo } from "../../types/DatosHorario"
import { TablaObserver } from "../TablaObserver" import { TablaObserver } from "../TablaObserver"
@ -32,6 +32,9 @@ const e = StyleSheet.create({
celdaSeleccionado: { celdaSeleccionado: {
textDecoration: "underline", textDecoration: "underline",
}, },
celdaOculto: {
opacity: 0.3,
},
}) })
const eColores = StyleSheet.create({ const eColores = StyleSheet.create({
@ -99,18 +102,15 @@ export function CeldaFila(props: Props) {
const esLab = datos.esLab const esLab = datos.esLab
const fnSeleccionar = datos.fnSeleccionar const fnSeleccionar = datos.fnSeleccionar
const estadoCeldaMemo = props.tablaObserver.registrarConId(id) const estadoCeldaMemo = props.tablaObserver.registrarConId(id, datos.datosGrupo)
const [estabaResaltado, setEstabaResaltado] = createSignal(false) const [estabaResaltado, setEstabaResaltado] = createSignal(false)
const estaSeleccionado = createMemo(() => datos.datosGrupo.seleccionado)
const clases = createMemo( const clases = createMemo(
() => { () => {
const clases = [ const clases = [
e.celdaCurso, e.celdaCurso,
esLab ? e.celdaCursoLab : e.celdaCursoTeoria, esLab ? e.celdaCursoLab : e.celdaCursoTeoria
estaSeleccionado() && e.celdaSeleccionado,
] ]
let adicional = "" let adicional = ""
@ -131,7 +131,7 @@ export function CeldaFila(props: Props) {
setEstabaResaltado(false) setEstabaResaltado(false)
} }
// TODO clases.push(e.celdaOculto)
break break
} }
case "Resaltado": { case "Resaltado": {
@ -147,6 +147,7 @@ export function CeldaFila(props: Props) {
setEstabaResaltado(false) setEstabaResaltado(false)
} }
clases.push(e.celdaSeleccionado)
break break
} }
case "ResaltadoOculto": { case "ResaltadoOculto": {

View File

@ -1,4 +1,11 @@
import { createMemo, createState, SetStateFunction, State } from "solid-js" import { createMemo, createState, SetStateFunction, State, produce, createEffect } from "solid-js"
import { DatosGrupo } from "../types/DatosHorario"
const createMemoDefault = <T>(f: () => T) => createMemo<T>(
f,
undefined,
(x, y) => x === y,
)
/** /**
* - Normal * - Normal
@ -16,22 +23,38 @@ type EstadoCelda =
| "ResaltadoSeleccionado" | "ResaltadoSeleccionado"
| "ResaltadoOculto" | "ResaltadoOculto"
interface Datos { type EstadoSeleccionado =
| "Seleccionado"
| "Oculto"
| "Normal"
interface IResaltado {
anio?: string, anio?: string,
curso?: string, curso?: string,
esLab?: boolean, esLab?: boolean,
grupo?: string, grupo?: string,
} }
interface ISeleccionado {
[anio: string]: {
[curso: string]: {
Laboratorio: string[]
Teoria: string[]
},
},
}
export class TablaObserver { export class TablaObserver {
private readonly resaltado: State<Datos> private readonly resaltado: State<IResaltado>
private readonly setResaltado: SetStateFunction<Datos> private readonly setResaltado: SetStateFunction<IResaltado>
private gruposSeleccionados = {} private memos: { [id: string]: () => EstadoCelda } = {}
private memos: {[id: string]: () => EstadoCelda} = {};
private readonly seleccionado: State<ISeleccionado>
private readonly setSeleccionado: SetStateFunction<ISeleccionado>
constructor() { constructor() {
const [resaltado, setResaltado] = createState<Datos>({ const [resaltado, setResaltado] = createState<IResaltado>({
anio: undefined, anio: undefined,
curso: undefined, curso: undefined,
esLab: undefined, esLab: undefined,
@ -39,6 +62,10 @@ export class TablaObserver {
}) })
this.resaltado = resaltado this.resaltado = resaltado
this.setResaltado = setResaltado this.setResaltado = setResaltado
const [seleccionado, setSeleccionado] = createState<ISeleccionado>({})
this.seleccionado = seleccionado
this.setSeleccionado = setSeleccionado
} }
/** /**
@ -47,55 +74,107 @@ export class TablaObserver {
* @param curso Curso abreviado * @param curso Curso abreviado
* @param esLab Si es laboratorio * @param esLab Si es laboratorio
* @param grupo Una única letra * @param grupo Una única letra
* @param datosGrupo Contiene `seleccionado`, se usa ese valor reactivo
*/ */
private registrar(anio: string, curso: string, esLab: boolean, grupo: string): () => EstadoCelda { private registrar(
anio: string,
curso: string,
esLab: boolean,
grupo: string,
datosGrupo: DatosGrupo,
): () => EstadoCelda {
const resaltado = this.resaltado const resaltado = this.resaltado
const resaltadoMemo = createMemo( const resaltadoMemo = createMemoDefault(() => {
() => { if (resaltado.anio === anio && resaltado.curso === curso) {
if (resaltado.anio === anio && resaltado.curso === curso) { if (resaltado.esLab === undefined) {
if (resaltado.esLab === undefined) { return true
return true } else if (resaltado.esLab !== esLab) {
} else if (resaltado.esLab !== esLab) {
return false
} else {
if (resaltado.grupo === undefined) {
return true
} else return resaltado.grupo === grupo;
}
} else {
return false return false
}
},
undefined,
(x, y) => x === y,
)
return createMemo(
(): EstadoCelda => {
if (resaltadoMemo()) {
return "Resaltado"
} else { } else {
return "Normal" if (resaltado.grupo === undefined) {
return true
} else return resaltado.grupo === grupo
} }
}, } else {
undefined, return false
(x, y) => x === y, }
) })
// Registrar curso en `seleccionado`
this.setSeleccionado((obj) => {
const nuevoObj = {...obj}
if (!nuevoObj[anio]) {
nuevoObj[anio] = {}
}
if (!nuevoObj[anio][curso]) {
nuevoObj[anio][curso] = {
Laboratorio: [],
Teoria: [],
}
}
return nuevoObj
})
// Crear un effect para que cada vez que la celda se seleccione se actualize `seleccionado`
createEffect(() => {
const seleccionado = datosGrupo.seleccionado
if (seleccionado){
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => [...x, grupo])
} else {
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => x.filter((x) => x !== grupo))
}
})
const seleccionadoMemo = createMemoDefault<EstadoSeleccionado>(() => {
const gruposSeleccionados = this.seleccionado[anio][curso][esLab ? "Laboratorio" : "Teoria"]
if (gruposSeleccionados.length > 0) {
return gruposSeleccionados.find((x) => x === grupo) ? "Seleccionado" : "Oculto"
} else {
return "Normal"
}
})
return createMemoDefault((): EstadoCelda => {
const resaltado = resaltadoMemo()
const seleccionado = seleccionadoMemo()
switch (seleccionado) {
case "Normal": {
return resaltado ? "Resaltado" : "Normal"
}
case "Oculto": {
return resaltado ? "ResaltadoOculto" : "Oculto"
}
case "Seleccionado": {
return resaltado ? "ResaltadoSeleccionado" : "Seleccionado"
}
default: {
let _: never
_ = seleccionado
return _
}
}
})
} }
/** /**
* Crea un memo que indica el estado de la celda a partir de un id * Crea un memo que indica el estado de la celda a partir de un id
* @param id Id a registrar - YYYYMMDD_Año_Curso[\_Lab[_Grupo]] * @param id Id a registrar - YYYYMMDD_Año_Curso[\_Lab[_Grupo]]
* @param datosGrupo Contiene `seleccionado`, se usa ese valor reactivo
*/ */
registrarConId(id: string): () => EstadoCelda { registrarConId(id: string, datosGrupo: DatosGrupo): () => EstadoCelda {
if (this.memos[id]) { if (this.memos[id]) {
return this.memos[id] return this.memos[id]
} }
const [, anio, curso, lab, grupo] = id.split("_") const [, anio, curso, lab, grupo] = id.split("_")
const memo = this.registrar(anio, curso, lab === "L", grupo) const memo = this.registrar(anio, curso, lab === "L", grupo, datosGrupo)
this.memos[id] = memo; this.memos[id] = memo
return memo; return memo
} }
/** /**