diff --git a/frontend/package.json b/frontend/package.json
index fc04c0f..0a933a4 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -7,7 +7,8 @@
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
- "lint": "eslint --fix"
+ "lint": "eslint --fix",
+ "typecheck": "tsc --noEmit"
},
"license": "MIT",
"devDependencies": {
diff --git a/frontend/src/certs/CustomLabelContext.tsx b/frontend/src/certs/CustomLabelContext.tsx
new file mode 100644
index 0000000..306c9c4
--- /dev/null
+++ b/frontend/src/certs/CustomLabelContext.tsx
@@ -0,0 +1,45 @@
+import { JSX, createContext, createMemo, createResource, useContext } from "solid-js";
+import { CustomLabel } from "../types/CustomLabel";
+import axios from "axios";
+
+export type CustomLabelsMap = {[custom_label_id: number]: CustomLabel};
+
+const CustomLabelContext = createContext<{
+ labels: () => CustomLabelsMap
+}>();
+
+export function CustomLabelProvider(props: {children: JSX.Element}) {
+ const [labels] = createResource(fetchAllLabels);
+
+ const customLabelData = {
+ labels: createMemo(() => labels() ?? {}),
+ };
+
+ return (
+
+ {props.children}
+
+ );
+}
+
+let cachedLabels: CustomLabelsMap | null = null;
+
+async function fetchAllLabels(useCache = true): Promise {
+ if (useCache && cachedLabels !== null) {
+ return cachedLabels;
+ }
+
+ const result = await axios.get>(`${import.meta.env.VITE_BACKEND_URL}/api/label`);
+
+ const map: CustomLabelsMap = {};
+ for (const label of result.data) {
+ map[label.custom_label_id] = label;
+ }
+
+ cachedLabels = map;
+ return map;
+}
+
+export function useCustomLabel() {
+ return useContext(CustomLabelContext);
+}
diff --git a/frontend/src/certs/NewRegister/CustomLabelSelect.tsx b/frontend/src/certs/NewRegister/CustomLabelSelect.tsx
index f0eec82..ea4008c 100644
--- a/frontend/src/certs/NewRegister/CustomLabelSelect.tsx
+++ b/frontend/src/certs/NewRegister/CustomLabelSelect.tsx
@@ -1,5 +1,5 @@
import { createEffect, createSignal, For, onMount } from "solid-js";
-import { customLabelsMap } from "../../utils/allCustomLabels";
+import { useCustomLabel } from "../CustomLabelContext";
export function CustomLabelSelect(props: {
onChange: (value: string) => void,
@@ -8,6 +8,7 @@ export function CustomLabelSelect(props: {
const [filter, setFilter] = createSignal("");
const [selected, setSelected] = createSignal(false);
const [inputValue, setInputValue] = createSignal("");
+ const customLabels = useCustomLabel();
const iHandler = (ev: KeyboardEvent & {currentTarget: HTMLInputElement, target: Element}) => {
const inputEl = ev.target as HTMLInputElement;
@@ -49,9 +50,13 @@ export function CustomLabelSelect(props: {
const filteredOptions = () => {
+ if (customLabels === undefined) {
+ return [];
+ }
+
const filterText = filter();
- return Object.entries(customLabelsMap()).filter(([, label]) => {
+ return Object.entries(customLabels.labels()).filter(([, label]) => {
let courseText = label.custom_label_value.toLowerCase();
courseText = courseText.replace("á", "a");
courseText = courseText.replace("é", "e");
diff --git a/frontend/src/certs/NewRegister/ManualRegistration.tsx b/frontend/src/certs/NewRegister/ManualRegistration.tsx
index dd376f3..0c60f78 100644
--- a/frontend/src/certs/NewRegister/ManualRegistration.tsx
+++ b/frontend/src/certs/NewRegister/ManualRegistration.tsx
@@ -2,8 +2,8 @@ import { JSX, Show, createSignal } from "solid-js";
import { SearchableSelect } from "./SearchableSelect";
import { CustomLabelSelect } from "./CustomLabelSelect";
import { RegistrationPreview } from ".";
-import { customLabelsMap } from "../../utils/allCustomLabels";
import { useCourses } from "../CourseContext";
+import { useCustomLabel } from "../CustomLabelContext";
type HTMLEventFn = JSX.EventHandlerUnion (v.custom_label_value === label))?.[1].custom_label_id ?? -1;
+ const custom_label_id = Object.entries(customLabels.labels()).find(([, v]) => (v.custom_label_value === label))?.[1].custom_label_id ?? -1;
const data: RegistrationPreview = {
courseId: subject,
diff --git a/frontend/src/certs/Registers/RegisterElement.tsx b/frontend/src/certs/Registers/RegisterElement.tsx
index 5c4155d..eeb5198 100644
--- a/frontend/src/certs/Registers/RegisterElement.tsx
+++ b/frontend/src/certs/Registers/RegisterElement.tsx
@@ -2,7 +2,6 @@ import { Show, createMemo } from "solid-js";
import { certGenerator } from "../../certGenerator";
import { Person } from "../../types/Person";
import { Register } from "../../types/Register";
-import { customLabelsMap } from "../../utils/allCustomLabels";
import { DownloadSimpleIcon } from "../../icons/DownloadSimpleIcon";
import { CaretRight } from "../../icons/CaretRight";
import { IdentificationCardIcon } from "../../icons/IdentificationCardIcon";
@@ -14,6 +13,7 @@ import { genMatpelCarnet } from "../../carnetGenerator/matpel";
import { genMachineryCarnet } from "../../carnetGenerator/machinery";
import { Course } from "../../types/Course";
import { useCourses } from "../CourseContext";
+import { CustomLabelsMap, useCustomLabel } from "../CustomLabelContext";
const carnetEnabled = [
"Matpel 3",
@@ -27,6 +27,7 @@ const carnetEnabled = [
export function RegisterElement(props: {register: Register, person: Person, onClick: () => void}) {
const courses = useCourses();
+ const customLabels = useCustomLabel();
const dateComponents = () => {
const [, year, month, day] = /(\d{4})-(\d{2})-(\d{2})/.exec(props.register.register_display_date) ?? [];
@@ -44,13 +45,18 @@ export function RegisterElement(props: {register: Register, person: Person, onCl
};
const customLabel = () => {
+ if (customLabels === undefined) {
+ return "~~Denominaciones no cargadas~~";
+ }
+
const labelId = props.register.register_custom_label;
if (labelId === 1) return "";
- return customLabelsMap()[labelId]?.custom_label_value ?? "";
+
+ return customLabels.labels()[labelId]?.custom_label_value ?? "~~Denominación no encontrada~~";
};
const genCert = () => {
- if (courses === undefined) {
+ if (courses === undefined || customLabels === undefined) {
alert("Error. La lista de cursos no esta cargada.");
return;
}
@@ -58,7 +64,7 @@ export function RegisterElement(props: {register: Register, person: Person, onCl
const person = props.person;
const register = props.register;
- generateCert(person, register, courses.idMap());
+ generateCert(person, register, courses.idMap(), customLabels.labels());
};
const generateable = () => {
@@ -164,7 +170,12 @@ export function RegisterElement(props: {register: Register, person: Person, onCl
);
}
-export function generateCert(person: Person, register: Register, coursesMap: {[course_id: number]: Course}) {
+export function generateCert(
+ person: Person,
+ register: Register,
+ coursesMap: {[course_id: number]: Course},
+ labelsMap: CustomLabelsMap,
+) {
const courseN = coursesMap[register.register_course_id]?.course_name ?? "Curso no encontrado";
const generator = certGenerator[courseN];
@@ -181,7 +192,7 @@ export function generateCert(person: Person, register: Register, coursesMap: {[c
if (register.register_custom_label === 1) {
certCustomLabel = "";
} else {
- const customLabel = customLabelsMap()[register.register_custom_label];
+ const customLabel = labelsMap[register.register_custom_label];
if (customLabel === undefined) {
alert(`Error. No se encontró la denominación con id ${register.register_custom_label}`);
return;
diff --git a/frontend/src/certs/Registers/index.tsx b/frontend/src/certs/Registers/index.tsx
index 2665319..5fa6eea 100644
--- a/frontend/src/certs/Registers/index.tsx
+++ b/frontend/src/certs/Registers/index.tsx
@@ -8,6 +8,7 @@ import { JsonResult } from "../../types/JsonResult";
import { LoadingIcon } from "../../icons/LoadingIcon";
import { RegisterElement, generateCert } from "./RegisterElement";
import { useCourses } from "../CourseContext";
+import { useCustomLabel } from "../CustomLabelContext";
export function Registers(props: {person: Person | null, count: number}) {
const [registers, setRegisters] = createSignal>([]);
@@ -16,6 +17,7 @@ export function Registers(props: {person: Person | null, count: number}) {
const [loading, setLoading] = createSignal(false);
const [error, setError] = createSignal("");
const courses = useCourses();
+ const customLabels = useCustomLabel();
const loadRegisters = async() => {
setLoading(true);
@@ -103,10 +105,10 @@ export function Registers(props: {person: Person | null, count: number}) {
const [downButtonBg, setDownButtonBg] = createSignal("bg-c-primary text-c-on-primary");
const downloadTodayCerts = () => {
- if (props.person === null || courses === undefined) return;
+ if (props.person === null || courses === undefined || customLabels === undefined) return;
todayRegisters().forEach((register) => {
- generateCert(props.person!, register, courses.idMap());
+ generateCert(props.person!, register, courses.idMap(), customLabels.labels());
});
setDownButtonBg("bg-c-success text-c-on-success");
diff --git a/frontend/src/certs/index.tsx b/frontend/src/certs/index.tsx
index 4f30b19..de47dad 100644
--- a/frontend/src/certs/index.tsx
+++ b/frontend/src/certs/index.tsx
@@ -1,10 +1,13 @@
import { CertsImpl } from "./CertsImpl";
import { CoursesProvider } from "./CourseContext";
+import { CustomLabelProvider } from "./CustomLabelContext";
export function Certs() {
return (
-
+
+
+
);
}
diff --git a/frontend/src/utils/allCustomLabels.ts b/frontend/src/utils/allCustomLabels.ts
index 3c02807..90fc198 100644
--- a/frontend/src/utils/allCustomLabels.ts
+++ b/frontend/src/utils/allCustomLabels.ts
@@ -1,10 +1,7 @@
-import { createSignal } from "solid-js";
import { CustomLabel } from "../types/CustomLabel";
type CustomLabelsMap = {[k: number]: CustomLabel};
-// TODO: Refactor, this is inefficient
-export const [customLabelsMap, setCustomLabelsMap] = createSignal<{[k: number]: CustomLabel}>({});
export function loadCustomLabels() {
fetch(`${import.meta.env.VITE_BACKEND_URL}/api/label`)
@@ -14,7 +11,6 @@ export function loadCustomLabels() {
for (const label of data) {
map[label.custom_label_id] = label;
}
- setCustomLabelsMap(map);
});
}