feat(portal): descarga del cronograma del proyecto en Excel
El cliente ya veía el roadmap en pantalla pero no tenía cómo pasárselo a alguien que no entra al portal. El .xlsx se genera con archive/zip + encoding/xml de la stdlib en vez de sumar una dependencia de Excel para una sola pantalla. Un CSV renombrado no servía: en Excel en español el separador y los acentos se rompen, y esto es un archivo que el cliente le entrega a un tercero. Detalles que hacen que Excel lo acepte y se lea bien: inline strings (sin tabla sharedStrings, así ningún índice puede apuntar a la cadena equivocada), encabezado en negrita y congelado, anchos de columna según el contenido, y nombre de hoja saneado (Excel rechaza el archivo si pasa de 31 caracteres o trae : \ / ? * [ ]). El endpoint repite el chequeo de acceso de PortalProyecto: sin eso, cualquiera con sesión de portal se bajaba el cronograma de otro cliente adivinando el slug. Verificado abriendo el archivo generado con openpyxl: 6 partes, CRC OK, XML bien formado en todas, acentos y CJK intactos, negrita y panel congelado donde corresponde. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5182c45d11
commit
62c644b815
@@ -40,6 +40,17 @@
|
||||
|
||||
<!-- ─── ROADMAP ────────────────────────────────────────────────────────────── -->
|
||||
<div x-show="activeTab==='Roadmap'" x-cloak>
|
||||
{{ if .fases }}
|
||||
<div class="flex justify-end mb-4">
|
||||
<a href="/portal/proyecto/{{ .proyecto.Slug }}/cronograma.xlsx"
|
||||
class="inline-flex items-center gap-2 text-sm font-medium text-slate-600 hover:text-slate-900 border border-slate-200 hover:border-slate-300 rounded-lg px-3 py-1.5 transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
Descargar cronograma (Excel)
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="relative">
|
||||
<!-- Línea vertical -->
|
||||
<div class="absolute left-6 top-0 bottom-0 w-0.5 bg-slate-200"></div>
|
||||
|
||||
Reference in New Issue
Block a user