211 lines
7.9 KiB
TypeScript
211 lines
7.9 KiB
TypeScript
// ============================================================
|
|
// SAM - Tipos, manifiesto de funciones API y helpers de UI
|
|
// Las funciones por módulo reflejan los controllers del
|
|
// backend compartido (SAM.API). El routing de ASP.NET Core
|
|
// es case-insensitive, por eso los paths van en minúsculas.
|
|
// ============================================================
|
|
|
|
export interface LastDeploy {
|
|
sha: string;
|
|
time: string;
|
|
ok: boolean;
|
|
log: string;
|
|
}
|
|
|
|
export interface ModuleState {
|
|
name: string;
|
|
repoUrl: string;
|
|
branch: string;
|
|
subdomain: string;
|
|
port: number;
|
|
active: boolean;
|
|
category?: string;
|
|
lastDeploy?: LastDeploy;
|
|
container?: string | null;
|
|
}
|
|
|
|
export interface ApiResponse {
|
|
backend: {
|
|
repoUrl: string;
|
|
branch: string;
|
|
container: string | null;
|
|
lastDeploy: LastDeploy | null;
|
|
};
|
|
modules: ModuleState[];
|
|
}
|
|
|
|
export interface ApiFunction {
|
|
label: string;
|
|
icon: string;
|
|
path: string;
|
|
desc: string;
|
|
}
|
|
|
|
export interface MenuItem {
|
|
label: string;
|
|
icon: string;
|
|
href: string;
|
|
}
|
|
|
|
const A = (
|
|
label: string,
|
|
icon: string,
|
|
path: string,
|
|
desc: string
|
|
): ApiFunction => ({ label, icon, path, desc });
|
|
|
|
// --- Conjuntos de funciones por familia de módulo ---
|
|
const CORE: ApiFunction[] = [
|
|
A("Alumnos", "bx-group", "api/alumnos", "Ficha, matrícula y sesiones de alumnos"),
|
|
A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios de cursos"),
|
|
A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos de profesores"),
|
|
A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio y propuestas"),
|
|
A("Pagos", "bx-money", "api/pagos", "Caja, cotizaciones y vouchers"),
|
|
A("Contratos", "bx-file", "api/contratos", "Contratos firmados y por firmar"),
|
|
A("Informes", "bx-bar-chart-alt-2", "api/informes", "Reportes académicos y de gestión"),
|
|
];
|
|
|
|
const FUNCTION_SETS: Record<string, ApiFunction[]> = {
|
|
academico: [
|
|
A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios"),
|
|
A("Alumnos", "bx-group", "api/alumnos/extra", "Ficha, matrícula y sesiones"),
|
|
A("Apoderados", "bx-user", "api/apoderados", "Apoderados y contactos"),
|
|
A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"),
|
|
A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"),
|
|
A("Feriados", "bx-calendar", "api/feriados", "Calendario de feriados"),
|
|
A("Placement Test", "bx-edit", "api/placement-test", "Pruebas de nivel"),
|
|
A("Plan Anual", "bx-calendar-alt", "api/plan-anual", "Planificación anual"),
|
|
],
|
|
profesores: [
|
|
A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos"),
|
|
A("Funciones Extra", "bx-plus-circle", "api/profesores/extra", "Operaciones extendidas"),
|
|
A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"),
|
|
A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"),
|
|
],
|
|
empresas: [
|
|
A("Propuestas", "bx-briefcase", "api/propuestas-empresa", "Propuestas a empresas"),
|
|
A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio"),
|
|
A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"),
|
|
A("Contratos", "bx-file", "api/contratos/extra", "Contratos con empresas"),
|
|
],
|
|
ventas: [
|
|
A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"),
|
|
A("Leads", "bx-target-lock", "api/leads/extra", "Prospectos y seguimiento"),
|
|
A("Ventas", "bx-cart", "api/ventas", "Ventas y cotizaciones"),
|
|
A("Cotizaciones", "bx-receipt", "api/cotizaciones", "Cotizaciones emitidas"),
|
|
A("Ejecutivos", "bx-user-voice", "api/ejecutivos", "Ejecutivos de venta"),
|
|
],
|
|
pagos: [
|
|
A("Portal Pagos", "bx-credit-card", "api/portal-pagos", "Pagos en línea"),
|
|
A("Pagos", "bx-money", "api/pagos", "Caja y vouchers"),
|
|
A("WebPay", "bx-card", "api/webpay", "Transacciones Transbank"),
|
|
A("Boletas", "bx-receipt", "api/boletas", "Boletas y facturación"),
|
|
A("Arqueo", "bx-calculator", "api/arqueocaja", "Arqueo de caja"),
|
|
],
|
|
contabilidad: [
|
|
A("Contabilidad", "bx-detail", "api/contabilidad", "Movimientos contables"),
|
|
A("Libros", "bx-book-open", "api/libros", "Libros de compra / venta"),
|
|
A("DTE", "bx-file-blank", "api/dte", "Documentos tributarios"),
|
|
A("Documentos", "bx-folder", "api/documentos", "Repositorio documental"),
|
|
],
|
|
};
|
|
|
|
const MODULE_FAMILY: Record<string, string> = {
|
|
academico: "academico",
|
|
"academico-empresas": "empresas",
|
|
portal: "empresas",
|
|
empresas: "empresas",
|
|
ventas: "ventas",
|
|
comercial: "ventas",
|
|
pagos: "pagos",
|
|
contabilidad: "contabilidad",
|
|
profesores: "profesores",
|
|
};
|
|
|
|
export function getModuleFunctions(name: string): ApiFunction[] {
|
|
const key = name.toLowerCase();
|
|
const family =
|
|
MODULE_FAMILY[key] ??
|
|
Object.keys(FUNCTION_SETS).find((f) => key.includes(f));
|
|
if (family && FUNCTION_SETS[family]) return FUNCTION_SETS[family];
|
|
return CORE;
|
|
}
|
|
|
|
// --- Meta visual por módulo (iconos boxicons + fondo) ---
|
|
const iconMap: Record<string, { icon: string; bg: string }> = {
|
|
sam: { icon: "bx-layer", bg: "bg-primary" },
|
|
ventas: { icon: "bx-money", bg: "bg-success" },
|
|
comercial: { icon: "bx-money", bg: "bg-success" },
|
|
finanzas: { icon: "bx-detail", bg: "bg-danger" },
|
|
contabilidad: { icon: "bx-detail", bg: "bg-danger" },
|
|
academico: { icon: "bx-user", bg: "bg-primary" },
|
|
"academico-empresas": { icon: "bx-briefcase", bg: "bg-primary" },
|
|
profesor: { icon: "bx-pencil", bg: "bg-warning text-dark" },
|
|
profesores: { icon: "bx-pencil", bg: "bg-warning text-dark" },
|
|
empresas: { icon: "bx-building", bg: "bg-info" },
|
|
portal: { icon: "bx-building", bg: "bg-info" },
|
|
pagos: { icon: "bx-credit-card", bg: "bg-success" },
|
|
default: { icon: "bx-cube", bg: "bg-secondary" },
|
|
};
|
|
|
|
export function getModuleMeta(name: string) {
|
|
return iconMap[name.toLowerCase()] || iconMap.default;
|
|
}
|
|
|
|
export function getStatusInfo(m: ModuleState) {
|
|
if (!m.container) return { label: "Detenido", cls: "status-unhealthy" };
|
|
if (m.container.includes("healthy"))
|
|
return { label: "Activo", cls: "status-healthy" };
|
|
if (m.container.includes("starting"))
|
|
return { label: "Iniciando", cls: "status-starting" };
|
|
return { label: "Activo", cls: "status-healthy" };
|
|
}
|
|
|
|
export function displayName(name: string) {
|
|
return name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, " ");
|
|
}
|
|
|
|
export function moduleUrl(m: ModuleState) {
|
|
return `https://${m.subdomain}.devops.norteamericano.cl`;
|
|
}
|
|
|
|
// ============================================================
|
|
// Secciones del índice: dónde aparece cada módulo.
|
|
// - Todo módulo nuevo cae en "apps" (Aplicaciones) automáticamente.
|
|
// - Para mover un módulo a otra sección, agrégalo a MODULE_SECTION.
|
|
// - Para crear una sección futura: agrega una entrada en SECTIONS
|
|
// (id, título, icono) y la regla en MODULE_SECTION o en
|
|
// sectionOf(). El índice la renderiza sola si tiene módulos.
|
|
// ============================================================
|
|
|
|
export interface Section {
|
|
id: string;
|
|
title: string;
|
|
icon: string;
|
|
}
|
|
|
|
export const SECTIONS: Section[] = [
|
|
{ id: "pagina-web", title: "Página Web", icon: "bx-globe" },
|
|
{ id: "sam", title: "SAM", icon: "bx-layer" },
|
|
{ id: "profesores", title: "Profesores", icon: "bx-pencil" },
|
|
{ id: "otras-apps", title: "Otras Aplicaciones", icon: "bx-cube" },
|
|
];
|
|
|
|
// Categoría que pregunta la integración (default del deployer: otras-apps).
|
|
// "Otras Aplicaciones" concentra la revisión prod/dev: módulos
|
|
// integrados + backend + gestión.
|
|
export function sectionOf(name: string, category?: string): string {
|
|
const c = (category || "").trim().toLowerCase();
|
|
if (c && SECTIONS.some((s) => s.id === c)) return c;
|
|
void name;
|
|
return "otras-apps";
|
|
}
|
|
|
|
// Rama main/master = producción, resto = desarrollo.
|
|
export function envOf(branch: string) {
|
|
const b = (branch || "").trim().toLowerCase();
|
|
return b === "main" || b === "master" || b === "prod" || b === "production"
|
|
? { label: "Prod", cls: "bg-success" }
|
|
: { label: "Dev", cls: "bg-warning text-dark" };
|
|
}
|