1import{a as R}from"./chunk-4PUGIRIL.js";import{Gc as p,hb as E}from"./chunk-5HK6ZSCG.js";import{a as f,b as v}from"./chunk-N4LVVBTG.js";var D=class u{items=p([]);fallback=p(null);dimensionOrder=p([]);dimensionMap=p({});periodoLabel=p("");static assetPath="/docs/evaluacion-docente-template";static templateImagesPromise;static chartBaseline=0;static chartCeiling=5;static dimensionReportLabels={A:"Dominio de la asignatura",B:"Planificaci\xF3n del curso",C:"Ambientes de aprendizaje",D:"Estrategias, m\xE9todos y t\xE9cnicas",E:"Motivaci\xF3n",F:"Evaluaci\xF3n",G:"Comunicaci\xF3n",H:"Gesti\xF3n del curso",I:"Tecnolog\xEDas de la informaci\xF3n y comunicaci\xF3n",J:"Satisfacci\xF3n general"};static scoreBands=[{min:4.75,label:"EXCELENTE",color:"#16a34a"},{min:4.21,label:"NOTABLE",color:"#f97316"},{min:3.76,label:"BUENO",color:"#f59e0b"},{min:3.3,label:"SUFICIENTE",color:"#eab308"},{min:0,label:"INSUFICIENTE",color:"#ef4444"}];async buildFromInputs(){let e=this.fallback();return e?u.build({items:this.items(),fallback:e,dimensionOrder:this.dimensionOrder(),dimensionMap:this.dimensionMap(),periodoLabel:this.periodoLabel()}):null}static async build(e){if(!e.items.length)throw new Error("No hay datos para generar el PDF de evaluaci\xF3n docente.");let[t,a]=await Promise.all([Promise.resolve(this.buildDataFromApi(e)),this.loadPdfTemplateImages()]);return{title:`Evaluaci\xF3n Docente - ${t.docenteNombre}`,htmlContent:this.renderHtml(t,a,e.dimensionMap),data:t}}static buildDataFromApi(e){let{items:t,fallback:a,dimensionOrder:i,dimensionMap:s,periodoLabel:o}=e,r=t[0],c=new Map(Object.entries(s).map(([n,l])=>[l,n])),d={};i.forEach(n=>{let m=`PROM_${c.get(n)||"J"}`;d[n]=this.weightedAverage(t,m)});let h=t.map(n=>({grupoId:R(n.GRUPO_ID??""),materia:n.MATERIA_DESCRIPCION||"",carrera:n.CARRERA||"",totalEstudiantes:Number(n.TOTAL_ESTUDIANTES||0),totalRespuestas:Number(n.TOTAL_RESPUESTAS||0)})).filter(n=>n.grupoId||n.materia),g=new Map;for(let n of h){let l=`${n.materia}::${n.grupoId}`,m=g.get(l);m?g.set(l,v(f({},m),{totalEstudiantes:m.totalEstudiantes+n.totalEstudiantes,totalRespuestas:m.totalRespuestas+n.totalRespuestas})):g.set(l,n)}let b=Array.from(g.values()).sort((n,l)=>String(n.materia).localeCompare(String(l.materia))),P=b.reduce((n,l)=>n+l.totalEstudiantes,0),w=b.reduce((n,l)=>n+l.totalRespuestas,0);return{docenteId:String(r.DOCENTE_ID??r.IDECATPRO??a.docenteId),docenteNombre:r.DOCENTE||r.NOMBRE_COMPLETO||a.docenteNombre,carrera:r.DESCRIPCION_ACADEMIA||r.CARRERA||a.carrera||String(r.AREA_ACADEMICA??""),encuesta:r.ENCUESTA||a.encuesta||"",periodo:String(r.PERIODO??a.periodo??""),periodoDesc:r.PERIODO_DESC||a.periodoDesc||o||"",totalEstudiantes:P||Number(a.totalEstudiantes||0),totalRespuestas:w||Number(a.totalRespuestas||0),materias:b,dimensiones:Object.keys(d).length?d:a.dimensiones||{},promedio:this.weightedAverage(t,"PROMEDIO_GENERAL")||Number(a.promedio||0)}}static loadPdfTemplateImages(){return this.templateImagesPromise||(this.templateImagesPromise=Promise.all([this.loadImageAsDataUrl("sep-gobierno.jpg"),this.loadImageAsDataUrl("tecnm.jpg"),this.loadImageAsDataUrl("watermark.jpg"),this.loadImageAsDataUrl("equidad-genero.png")]).then(([e,t,a,i])=>({sepGobierno:e,tecnm:t,watermark:a,equidadGenero:i})).catch(e=>{throw this.templateImagesPromise=void 0,e})),this.templateImagesPromise}static async loadImageAsDataUrl(e){let t=await fetch(`${this.assetPath}/${e}`,{cache:"force-cache"});if(!t.ok)throw new Error(`No se pudo cargar ${e}`);let a=await t.blob();return new Promise((i,s)=>{let o=new FileReader;o.onload=()=>i(String(o.result||"")),o.onerror=()=>s(o.error||new Error(`No se pudo leer ${e}`)),o.readAsDataURL(a)})}static renderHtml(e,t,a){let i=this.buildMateriasReportRows(e),s=this.buildAspectosReportRows(e,a),o=this.buildReportChartBars(e,a),r=this.buildReportChartLabels(e,a),c=this.escapeHtml(e.periodoDesc||e.periodo),d=this.escapeHtml(e.docenteNombre),h=this.escapeHtml(e.carrera);return`<!doctype html> 2<html lang="es"> 3<head> 4 <meta charset="utf-8"> 5 <title>${d}</title> 6 <style> 7 @page { size: A4 portrait; margin: 8mm; } 8 * { box-sizing: border-box; } 9 body { 10 margin: 0; 11 background: #f3f4f6; 12 color: #111827; 13 font-family: Arial, Helvetica, sans-serif; 14 } 15 .sheet { 16 width: 194mm; 17 min-height: 281mm; 18 margin: 0 auto; 19 padding: 8mm 10mm 21mm; 20 position: relative; 21 overflow: visible; 22 background: #fff; 23 } 24 .watermark { 25 position: absolute; 26 width: 150mm; 27 left: 22mm; 28 top: 56mm; 29 opacity: 0.82; 30 z-index: 0; 31 } 32 .content { position: relative; z-index: 1; } 33 .brand-header { 34 display: grid; 35 grid-template-columns: 44mm 1fr 31mm; 36 align-items: start; 37 gap: 5mm; 38 min-height: 31mm; 39 } 40 .logo-sep { width: 42mm; height: auto; } 41 .logo-tecnm { width: 30mm; height: auto; margin-top: 2mm; } 42 .institution { 43 text-align: center; 44 line-height: 1.18; 45 font-size: 8.8px; 46 } 47 .institution strong { 48 display: block; 49 font-size: 10px; 50 margin: 1mm 0; 51 } 52 h1 { 53 margin: 2mm 0 1.5mm; 54 text-align: center; 55 font-size: 15px; 56 font-weight: 700; 57 } 58 .meta { 59 display: grid; 60 grid-template-columns: 1fr 1fr; 61 gap: 1.4mm 5mm; 62 margin: 0 0 3mm; 63 font-size: 10px; 64 } 65 .meta .full { grid-column: 1 / -1; } 66 .meta b { font-weight: 700; } 67 .section-title { 68 margin: 3mm 0 1.2mm; 69 font-size: 11px; 70 font-weight: 700; 71 } 72 table { 73 width: 100%; 74 border-collapse: collapse; 75 font-size: 9px; 76 background: transparent; 77 } 78 th, td { 79 padding: 1.15mm 1.4mm; 80 border-bottom: 0.2mm solid #d1d5db; 81 vertical-align: top; 82 } 83 th { 84 font-weight: 700; 85 text-align: left; 86 background: transparent; 87 } 88 td.num, th.num { text-align: right; white-space: nowrap; } 89 .total-row td { 90 font-weight: 700; 91 background: transparent; 92 } 93 .aspect-table td:nth-child(2), 94 .aspect-table td:nth-child(3) { 95 text-align: right; 96 white-space: nowrap; 97 } 98 .aspect-table td:nth-child(3) { font-weight: 700; }
99 .chart-title { 100 margin-top: 3mm; 101 font-size: 10px; 102 font-weight: 700; 103 text-align: center; 104 } 105 .chart { 106 height: 54mm; 107 margin-top: 1mm; 108 padding: 2mm 3mm 0; 109 border-left: 0.2mm solid #111827; 110 border-bottom: 0.2mm solid #111827; 111 display: grid; 112 grid-template-columns: repeat(11, 1fr); 113 gap: 1.2mm; 114 align-items: end; 115 background: 116 linear-gradient(to top, transparent 0, transparent 19%, rgba(17,24,39,0.12) 20%, transparent 21%), 117 linear-gradient(to top, transparent 0, transparent 39%, rgba(17,24,39,0.12) 40%, transparent 41%), 118 linear-gradient(to top, transparent 0, transparent 59%, rgba(17,24,39,0.12) 60%, transparent 61%), 119 linear-gradient(to top, transparent 0, transparent 79%, rgba(17,24,39,0.12) 80%, transparent 81%); 120 } 121 .bar-wrap { 122 height: 48mm; 123 display: flex; 124 flex-direction: column; 125 justify-content: flex-end; 126 align-items: center; 127 min-width: 0; 128 } 129 .chart-outer { 130 display: flex; 131 align-items: flex-end; 132 gap: 1mm; 133 } 134 .y-axis-label-wrap { 135 display: flex; 136 align-items: center; 137 gap: 1mm; 138 } 139 .y-axis-title-container { 140 width: 12px; 141 height: 44mm; 142 margin-bottom: 4mm; 143 position: relative; 144 flex-shrink: 0; 145 } 146 .y-axis-title { 147 position: absolute; 148 top: 50%; 149 left: 50%; 150 transform: translate(-50%, -50%) rotate(-90deg); 151 font-size: 12px; 152 font-weight: 700; 153 color: #374151; 154 white-space: nowrap; 155 } 156 .x-axis-title { 157 text-align: center; 158 font-size: 12px; 159 font-weight: 700; 160 color: #374151; 161 margin-top: 1mm; 162 } 163 .y-axis { 164 display: flex; 165 flex-direction: column-reverse; 166 justify-content: space-between; 167 width: 4mm; 168 height: 44mm; 169 margin-bottom: 4mm; 170 text-align: right; 171 padding-right: 0.5mm; 172 } 173 .y-axis span { 174 font-size: 6.5px; 175 color: #4b5563; 176 font-weight: 600; 177 line-height: 1; 178 } 179 .bar { 180 width: 8.2mm; 181 min-height: 4mm; 182 background: #ff5a1f; 183 display: flex; 184 flex-direction: column; 185 align-items: center; 186 justify-content: flex-start; 187 color: #fff; 188 font-size: 7.5px; 189 font-weight: 700; 190 padding-top: 1mm; 191 overflow: visible; 192 position: relative; 193 } 194 .bar.total { background: #0b7a0b; width: 9mm; } 195 .bar-total-label { 196 position: absolute; 197 top: 50%; 198 left: 50%; 199 transform: translate(-50%, -50%) rotate(-90deg); 200 white-space: nowrap; 201 font-size: 5px; 202 font-weight: 700; 203 color: #fff; 204 text-align: center; 205 line-height: 1; 206 } 207 .chart-and-labels { 208 flex: 1; 209 display: flex; 210 flex-direction: column; 211 min-width: 0; 212 } 213 .bar-labels-row { 214 display: grid; 215 grid-template-columns: repeat(11, 1fr); 216 gap: 1.2mm; 217 margin-top: 0.8mm; 218 } 219 .bar-label { 220 font-size: 8px; 221 font-weight: 700; 222 text-align: center; 223 } 224 .signature { 225 margin: 9mm auto 0; 226 width: 74mm; 227 text-align: center; 228 font-size: 9px; 229 color: #111827; 230 } 231 .signature-line { 232 border-top: 0.25mm solid #111827; 233 margin-bottom: 1.4mm; 234 height: 0; 235 } 236 .footer-note { 237 position: absolute; 238 left: 10mm; 239 right: 25mm; 240 bottom: 8mm; 241 font-size: 8px; 242 color: #4b5563; 243 text-align: left; 244 z-index: 1; 245 } 246 .footer-logo { 247 position: absolute; 248 right: 10mm; 249 bottom: 5.5mm; 250 width: 15mm; 251 height: auto; 252 z-index: 1; 253 } 254 </style> 255</head> 256<body> 257 <main class="sheet"> 258 <img class="watermark" src="${t.watermark}" alt=""> 259 <section class="content"> 260 <header class="brand-header"> 261 <img class="logo-sep" src="${t.sepGobierno}" alt="SEP"> 262 <div class="institution"> 263 Secretar\xEDa de Educaci\xF3n Superior<br> 264 Tecnol\xF3gico Nacional de M\xE9xico<br> 265 <strong>Instituto Tecnol\xF3gico Superior de Nuevo Casas Grandes</strong> 266 </div> 267 <div> 268 <img class="logo-tecnm" src="${t.tecnm}" alt="TecNM"> 269 </div> 270 </header> 271 272 <h1>Evaluaci\xF3n por Docentes</h1> 273 274 <section class="meta"> 275 <div><b>Tipo de Evaluaci\xF3n:</b> Por Alumnos</div> 276 <div><b>Periodo:</b> ${c}</div> 277 <div class="full"><b>Evaluaci\xF3n del Docente:</b> ${d}</div> 278 <div class="full"><b>Academia:</b> ${h}</div> 279 </section> 280 281 <div class="section-title">Materias</div> 282 <table> 283 <thead> 284 <tr> 285 <th style="width: 23mm;">Clave Grupo</th> 286 <th>Nombre Completo De La Materia</th> 287 <th class="num" style="width: 19mm;">Inscritos</th> 288 <th class="num" style="width: 18mm;">Evaluaron</th> 289 </tr> 290 </thead> 291 <tbody> 292 ${i} 293 <tr class="total-row"> 294 <td colspan="2">TOTAL:</td> 295 <td class="num">${e.totalEstudiantes}</td> 296 <td class="num">${e.totalRespuestas}</td> 297 </tr> 298 </tbody> 299 </table> 300 301 <div class="section-title">Aspectos a Evaluar:</div> 302 <table class="aspect-table"> 303 <thead> 304 <tr> 305 <th>Aspectos Evaluados</th> 306 <th style="width: 22mm;">Puntaje</th> 307 <th style="width: 28mm;">Calificacion</th> 308 </tr> 309 </thead> 310 <tbody> 311 ${s} 312 <tr class="total-row"> 313 <td>TOTAL:</td> 314 <td>${this.formatScore(e.promedio)}</td> 315 <td>${this.escapeHtml(this.getScoreBand(e.promedio).label)}</td> 316 </tr> 317 </tbody> 318 </table> 319 320 <div class="chart-title">Resultado Gr\xE1fico:</div> 321 <div class="chart-outer"> 322 <div class="y-axis-label-wrap"> 323 <div class="y-axis-title-container">
324 <span class="y-axis-title">Porcentajes</span> 325 </div> 326 <div class="y-axis"> 327 <span>0</span> 328 <span>1</span> 329 <span>2</span> 330 <span>3</span> 331 <span>4</span> 332 <span>5</span> 333 </div> 334 </div> 335 <div class="chart-and-labels"> 336 <div class="chart" aria-label="Resultado gr\xE1fico"> 337 ${o} 338 </div> 339 <div class="bar-labels-row"> 340 ${r} 341 </div> 342 <div class="x-axis-title">Aspectos evaluados</div> 343 </div> 344 </div> 345 346 <div class="signature"> 347 <div class="signature-line"></div> 348 Firma del docente 349 </div> 350 </section> 351 <div class="footer-note"> 352 Av. Tecnologico # 7100 Km. 5 Carretera Nuevo Casas Grandes - Sueco C.P. 31789<br> 353 Nuevo Casas Grandes, Chih. Tel(s). 636 692 95 00 Fax 636 692 95 25<br> 354 Correo: [email protected], [email protected], [email protected] 355 </div> 356 <img class="footer-logo" src="${t.equidadGenero}" alt="Modelo de equidad de g\xE9nero"> 357 </main> 358</body> 359</html>`}static buildMateriasReportRows(e){return e.materias.length?e.materias.map(t=>` 360 <tr> 361 <td>${this.escapeHtml(t.grupoId)}</td> 362 <td>${this.escapeHtml(t.materia)}</td> 363 <td class="num">${t.totalEstudiantes}</td> 364 <td class="num">${t.totalRespuestas}</td> 365 </tr>`).join(""):'<tr><td colspan="4">Sin materias registradas.</td></tr>'}static buildAspectosReportRows(e,t){return this.getDimensionReportItems(e,t).map(a=>` 366 <tr> 367 <td>${a.key}) ${this.escapeHtml(a.label)}</td> 368 <td>${this.formatScore(a.value)}</td> 369 <td>${this.escapeHtml(a.calificacion)}</td> 370 </tr>`).join("")}static buildReportChartBars(e,t){return[...this.getDimensionReportItems(e,t).map(i=>({label:i.key,value:i.value,total:!1})),{label:"Prom.",value:e.promedio,total:!0}].map(i=>{let s=Number.isFinite(i.value)?i.value:0,o=Math.max(5,Math.min(100,this.getChartBarHeight(s))),r=i.total?"bar total":"bar",c=i.total?`${this.formatScore(s)}<span class="bar-total-label">Promedio General</span>`:this.formatScore(s);return` 371 <div class="bar-wrap"> 372 <div class="${r}" style="height: ${o.toFixed(2)}%;"> 373 ${c} 374 </div> 375 </div>`}).join("")}static buildReportChartLabels(e,t){return[...this.getDimensionReportItems(e,t).map(i=>({label:i.key,total:!1})),{label:"Prom.",total:!0}].map(i=>`<div class="bar-label">${this.escapeHtml(i.label)}</div>`).join("")}static getDimensionReportItems(e,t){return Object.keys(this.dimensionReportLabels).map(a=>{let i=t[a]||"",s=Number(e.dimensiones[i]||0);return{key:a,label:this.dimensionReportLabels[a],value:s,calificacion:this.getScoreBand(s).label}})}static weightedAverage(e,t){let a=0,i=0,s=[];return e.forEach(o=>{let r=Number(o[t]??0);if(!Number.isFinite(r))return;s.push(r);let c=Number(o.TOTAL_RESPUESTAS||0);Number.isFinite(c)&&c>0&&(a+=r*c,i+=c)}),i>0?a/i:s.length?s.reduce((o,r)=>o+r,0)/s.length:0}static getChartBarHeight(e){return(Math.min(this.chartCeiling,Math.max(this.chartBaseline,e))-this.chartBaseline)/(this.chartCeiling-this.chartBaseline)*100}static formatScore(e){return e==null||Number.isNaN(e)?"-":e.toFixed(2)}static getScoreBand(e){return this.scoreBands.find(t=>e>=t.min)??this.scoreBands[this.scoreBands.length-1]}static escapeHtml(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static \u0275fac=function(t){return new(t||u)};static \u0275cmp=E({type:u,selectors:[["app-evaluacion-docente-pdf"]],inputs:{items:[1,"items"],fallback:[1,"fallback"],dimensionOrder:[1,"dimensionOrder"],dimensionMap:[1,"dimensionMap"],periodoLabel:[1,"periodoLabel"]},decls:0,vars:0,template:function(t,a){},encapsulation:2})};export{D as EvaluacionDocentePdfComponent};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.