139 lines
4.1 KiB
TypeScript
139 lines
4.1 KiB
TypeScript
// Filtros globales del dashboard (sidebar)
|
|
export interface DashboardFilters {
|
|
depto?: string
|
|
genero?: string[]
|
|
etario?: string[]
|
|
modalidad?: string[]
|
|
}
|
|
|
|
// Estado de cada widget
|
|
export type WidgetStatus = 'loading' | 'ok' | 'suppressed' | 'error'
|
|
|
|
export type SuppressedPayload = { status: 'suppressed'; min_n: number; n: number }
|
|
|
|
export type RpcResult<T> = T | SuppressedPayload
|
|
|
|
export function isSuppressed(r: unknown): r is SuppressedPayload {
|
|
return typeof r === 'object' && r !== null && (r as Record<string, unknown>)['status'] === 'suppressed'
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════
|
|
// Mirada Empresa — shapes tal cual los devuelven las rpc_me_*
|
|
// (migración 20260625000002_dashboard_mirada_empresa.sql, verificada
|
|
// contra Postgres real). NO copiar del SPEC_MIRADA_EMPRESA.md a ciegas:
|
|
// el SQL real difiere un poco del shape ilustrativo de la spec (ej. E6
|
|
// agrega apoyo_percibido_suppressed; E7 usa "apoyos", no "data").
|
|
// ════════════════════════════════════════════════════════════
|
|
|
|
// E1 — Prevalencia de cuidadores
|
|
export interface PrevalenciaCuidadoresData {
|
|
status: 'ok'
|
|
n: number
|
|
pct_cuidadores: number
|
|
}
|
|
|
|
// E2 — Riesgo de rotación
|
|
export interface RiesgoRotacionData {
|
|
status: 'ok'
|
|
n_cuidadores: number
|
|
pct_riesgo: number
|
|
desglose: { algo: number; muy: number }
|
|
}
|
|
|
|
// E3 — Ausentismo
|
|
export interface AusentismoData {
|
|
status: 'ok'
|
|
n: number
|
|
pct_ausentismo_recurrente: number
|
|
desglose: { nunca: number; pocas: number; varias: number; frecuente: number }
|
|
}
|
|
|
|
// E4 — Presentismo
|
|
export interface PresentismoData {
|
|
status: 'ok'
|
|
n: number
|
|
pct_presentismo: number
|
|
desglose: {
|
|
nunca_o_casi_nunca: number
|
|
algunas_al_mes: number
|
|
varias_por_semana: number
|
|
casi_todos_los_dias: number
|
|
}
|
|
}
|
|
|
|
// E6 — Punto ciego organizacional
|
|
// apoyo_percibido_pct puede ser null con status='ok' si SU población (9.1)
|
|
// no llega a 5, aunque el total (carga_real) sí — dos poblaciones, dos
|
|
// supresiones independientes (ver comentario en la RPC).
|
|
export interface PuntoCiegoData {
|
|
status: 'ok'
|
|
n: number
|
|
carga_real_pct: number
|
|
apoyo_percibido_pct: number | null
|
|
apoyo_percibido_suppressed: boolean
|
|
brecha_pp: number | null
|
|
}
|
|
|
|
// E7 — Apoyos demandados
|
|
export interface ApoyoMEItem { apoyo: string; n: number; pct: number }
|
|
export interface ApoyosMEData {
|
|
status: 'ok'
|
|
n: number
|
|
apoyos: ApoyoMEItem[]
|
|
}
|
|
|
|
// ★ Talento en riesgo
|
|
export interface TalentoRiesgoData {
|
|
status: 'ok'
|
|
n_cuidadores: number
|
|
umbral_senales: number
|
|
pct_talento_riesgo: number
|
|
criterios_promedio: number
|
|
}
|
|
|
|
// E5 — Carrera congelada [SEC]
|
|
export interface CarreraCongeladaItem { opcion: string; n: number; pct: number }
|
|
export interface CarreraCongeladaData {
|
|
status: 'ok'
|
|
n: number
|
|
pct_carrera_congelada: number
|
|
top_opciones: CarreraCongeladaItem[]
|
|
}
|
|
|
|
// E8 — Intensidad de carga [SEC]
|
|
export interface IntensidadCargaCell {
|
|
dias_semana: string
|
|
horas_dia: string
|
|
n: number | null
|
|
suppressed: boolean
|
|
}
|
|
export interface IntensidadCargaData {
|
|
status: 'ok'
|
|
n: number
|
|
distribucion_intensidad: IntensidadCargaCell[]
|
|
pct_guardia_permanente: number
|
|
}
|
|
|
|
// E9 — Segmentación por nivel y modalidad [SEC]
|
|
export interface SegmentoNivelItem { nivel: string; n: number; pct: number }
|
|
export interface SegmentoModalidadItem { modalidad: string; n: number; pct: number }
|
|
export interface SegmentacionData {
|
|
status: 'ok'
|
|
n: number
|
|
por_nivel: SegmentoNivelItem[]
|
|
por_modalidad: SegmentoModalidadItem[]
|
|
}
|
|
|
|
// E10 — Disposición a red de apoyo [SEC]
|
|
// Shape "suppressed" de esta RPC difiere del genérico (usa
|
|
// n_grupo_apoyo/n_voluntariado, no min_n/n) — isSuppressed() solo mira
|
|
// `status`, así que sigue funcionando; no leer .n de un resultado
|
|
// suprimido de esta RPC en particular.
|
|
export interface DisposicionRedData {
|
|
status: 'ok'
|
|
n_grupo_apoyo: number
|
|
pct_grupo_apoyo: number | null
|
|
n_voluntariado: number
|
|
pct_voluntariado: number | null
|
|
}
|