Răsfoiți Sursa

First version of PAM task

Drowsito 4 săptămâni în urmă
părinte
comite
e00321ae4c

BIN
src/main/resources/static/E_PG1_1.pdf


+ 218 - 0
src/main/resources/static/css/saic.css

@@ -1301,3 +1301,221 @@ option {
 	padding-left: 2px;
 }
 
+/*****************************************************************************************/
+/*** PAM TABLE
+/*****************************************************************************************/
+.uv-table-pam-modern {
+	border-collapse: collapse !important;
+	font-family: 'Verdana', Geneva, sans-serif;
+	font-size: 0.8rem;
+	width: 100% !important;
+}
+.uv-table-pam-modern thead th {
+	background-color: #355d7e;
+	color: #ffffff;
+	text-align: center;
+	text-transform: uppercase;
+	padding: 10px !important;
+	border: 1px solid #dee2e6;
+}
+.uv-table-pam-modern .subheader th {
+	background-color: #e9f0f6;
+	color: #000000;
+	font-weight: bold;
+	font-size: 0.75rem;
+	padding: 8px !important;
+	text-align: center;
+}
+.uv-table-pam-modern td {
+	background-color: #ffffff;
+	padding: 6px !important;
+	vertical-align: top;
+	border: 1px solid #dee2e6;
+}
+.uv-table-pam-modern input, 
+.uv-table-pam-modern select, 
+.uv-table-pam-modern textarea {
+	font-size: 0.75rem !important;
+	border: 1px solid #ced4da;
+	width: 100%;
+}
+
+.uv-table-pam-modern .form-control-sm {
+	font-size: 0.6rem !important; 
+    line-height: 1.2;
+    padding: 4px 8px;
+}
+
+.uv-table-pam-modern textarea.form-control {
+	overflow: hidden;
+	resize: none;
+	min-height: 31px;
+}
+
+.col-id { width: 70px; }
+.col-prioridad { width: 90px; }
+.col-curso { width: 90px; }
+.col-seguimiento { width: 80px; }
+
+.pdf-widget {
+    position: fixed;
+    top: 150px;
+    right: 20px;
+    width: 70px;
+    height: 50px;
+    background: #004481; 
+    color: #fff;
+    border-radius: 8px;
+    box-shadow: 0 4px 10px rgba(0,0,0,0.3);
+    z-index: 9999;
+    cursor: grab;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    border: 1px solid #003366;
+    transition: transform 0.2s, background 0.2s;
+}
+
+.pdf-widget:hover {
+    background: #0056a3;
+    transform: scale(1.05);
+}
+
+.pdf-widget i {
+    font-size: 20px;
+}
+
+.pdf-widget span {
+    font-size: 8px;
+    font-weight: bold;
+    margin-top: 2px;
+}
+
+.pdf-preview-side {
+    position: fixed;
+    top: 60px;
+    bottom: 20px;
+    width: 45%;
+    background: #f8f9fa;
+    border: 1px solid #dee2e6;
+    box-shadow: -10px 0 25px rgba(0,0,0,0.2);
+    z-index: 10000;
+    display: none;
+    flex-direction: column;
+    border-radius: 8px 0 0 8px;
+    overflow: hidden;
+}
+
+.pdf-preview-header {
+    background: #343a40;
+    color: white;
+    padding: 8px 15px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 0.85rem;
+}
+
+.btn-close-pdf {
+    background: transparent;
+    border: none;
+    color: white;
+    font-size: 20px;
+    line-height: 1;
+    cursor: pointer;
+    padding: 0 5px;
+}
+
+.btn-close-pdf:hover {
+    color: #ff4d4d;
+}
+
+.pdf-preview-side.active-split {
+    position: fixed;
+    z-index: 1050;
+    width: 45% !important;
+}
+
+.table-responsive {
+    transition: all 0.3s ease-in-out;
+    display: block;
+    width: 100%;
+}
+
+/* Las clases de empuje */
+.table-split-right { 
+    width: 45% !important;
+    margin-right: 45% !important;
+    margin-left: 0 !important;
+}
+
+.table-split-left { 
+    width: 55% !important;
+    margin-left: 45% !important;
+    margin-right: 0 !important;
+}
+
+/* --- VISTA COMPACTA ADAPTATIVA (Flexbox Auto) --- */
+
+.uv-table-pam-modern.compact-mode thead {
+    display: none !important;
+}
+
+.uv-table-pam-modern.compact-mode tbody tr {
+    display: flex;
+    flex-wrap: wrap; 
+    margin-bottom: 20px;
+    border: 1px solid #1B3552 !important;
+    border-radius: 4px;
+    background-color: white;
+    overflow: hidden;
+}
+
+.uv-table-pam-modern.compact-mode td {
+    display: block;
+    padding: 10px !important;
+    border: 1px solid #e9ecef !important;
+    flex: 1 1 auto; 
+    min-width: 150px; 
+    box-sizing: border-box;
+}
+
+.uv-table-pam-modern.compact-mode td:nth-child(1) {
+    flex: 0 0 60px; 
+    min-width: 60px;
+}
+
+.uv-table-pam-modern.compact-mode td:nth-child(4) {
+    flex: 1 1 100% !important;
+    border-top: 2px solid #e9f0f6 !important;
+}
+
+.uv-table-pam-modern.compact-mode td:nth-child(9) {
+    border-left: 5px solid #e9f0f6 !important;
+}
+
+.uv-table-pam-modern.compact-mode td::before {
+    content: attr(data-label);
+    display: block;
+    font-size: 0.7rem;
+    font-weight: bold;
+    color: #1B3552;
+    text-transform: uppercase;
+    margin-bottom: 4px;
+}
+
+.uv-table-pam-modern.compact-mode td:nth-child(-n+3) { background-color: #f8fbff; } 
+.uv-table-pam-modern.compact-mode td:nth-child(n+9) { background-color: #f4faf4; } 
+
+.uv-table-pam-modern.compact-mode td:nth-child(1)::before { content: "ID"; }
+.uv-table-pam-modern.compact-mode td:nth-child(2)::before { content: "Objetivo de mejora"; }
+.uv-table-pam-modern.compact-mode td:nth-child(3)::before { content: "Origen"; }
+.uv-table-pam-modern.compact-mode td:nth-child(4)::before { content: "Actividades a desarrollar"; }
+.uv-table-pam-modern.compact-mode td:nth-child(5)::before { content: "Responsable"; }
+.uv-table-pam-modern.compact-mode td:nth-child(6)::before { content: "Prioridad"; }
+.uv-table-pam-modern.compact-mode td:nth-child(7)::before { content: "C. Inicio"; }
+.uv-table-pam-modern.compact-mode td:nth-child(8)::before { content: "C. Fin"; }
+.uv-table-pam-modern.compact-mode td:nth-child(9)::before { content: "Indicadores"; }
+.uv-table-pam-modern.compact-mode td:nth-child(10)::before { content: "Ejecución"; }
+.uv-table-pam-modern.compact-mode td:nth-child(11)::before { content: "Justificación"; }

+ 433 - 4
src/main/resources/templates/procedure.html

@@ -227,11 +227,74 @@
 														</div>
 													</div>
 												</div>
+												<div class="card-body-inner-action" th:if="${item.tipus == 3}">
+													<div id="pamSplitContainer" class="split-view-conttainer">
+
+													</div>
+													<div class="table-responsive">
+														<table class="table table-bordered uv-table-pam-modern" id="pamTable">
+															<thead>
+																<tr>
+																	<th colspan="3">ORIGEN DE LA ACCIÓN</th>
+																	<th colspan="5">ACCIÓN PLANIFICADA</th>
+																	<th colspan="3">SEGUIMIENTO</th>
+																</tr>
+																<tr class="subheader">
+																	<th class="col-id">ID</th>
+																	<th>Objetivo de mejora</th>
+																	<th>Origen</th>
+																	<th>Actividades a desarrollar</th>
+																	<th>Responsable</th>
+																	<th class="col-prioridad">Prioridad</th>
+																	<th class="col-curso">Curso Inicio</th>
+																	<th class="col-curso">Curso Fin</th>
+																	<th>Indicadores de seguimiento</th>
+																	<th class="col-seguimiento">Grado de ejecución de las acciones</th>
+																	<th>Justificación</th>
+																</tr>
+															</thead>
+															<tbody>
+															</tbody>
+														</table>
+													</div>
+
+													<div class="text-left mt-3 mb-4">
+														<button type="button" class="btn btn-outline-primary btn-sm" onclick="addNewRowPAM()">
+															<i class="fas fa-plus"></i> Añadir otra fila al Plan de Acción
+														</button>
+													</div>
+													<div id="pdfWidget" class="pdf-widget">
+														<div id="pdfWidgetHeader" class="pdf-widget-header">
+															<i class="fas fa-file-pdf"></i> 
+															<span>Informe</span>
+														</div>
+													</div>
+
+													<div id="pdfPreviewContainer" class="pdf-preview-side">
+														<div class="pdf-preview-header">
+															<span><i class="fas fa-info-circle mr-2"></i> Documentación de apoyo</span>
+															<button type="button" class="btn-close-pdf" onclick="closePdfPreview(event)">
+																&times;
+															</button>
+														</div>
+														<div style="flex-grow: 1; background: #525659;">
+															<iframe th:src="@{/E_PG1_1.pdf}" frameborder="0" style="width:100%; height:100%;"></iframe>
+														</div>
+													</div>
+												</div>
 												<div class="row card-body-up-btn">
 													<span class="btn btn-primary pointer" th:if="${#lists.contains({11, 15}, item.tipus)}" style="margin-right:10px;" onclick="saveEditorWithConfirmation();"><i class="fas fa-save"></i> <span th:text="#{procedures.btn.draft}">Guardar borrador</span></span>
-													<button class="btn btn-success" th:if="${not #lists.contains({1, 11, 12, 13, 14, 15}, item.tipus)}">Confirmar</button>
+													<span class="btn btn-primary pointer" th:if="${item.tipus == 3}" 
+														style="margin-right:10px;" onclick="processPAMTable('draft');">
+														<i class="fas fa-save"></i> <span th:text="#{procedures.btn.draft}">Guardar borrador</span>
+													</span>
+													<button class="btn btn-success" th:if="${not #lists.contains({1, 3, 11, 12, 13, 14, 15}, item.tipus)}">Confirmar</button>
 													<button class="btn btn-success" th:if="${#lists.contains({11, 15}, item.tipus)}" data-toggle="confirmation" th:attr="data-title=#{procedures.editor.confirm}"><i class="fas fa-file-import"></i> Enviar</button>
 													<span class="btn btn-success pointer" th:if="${#lists.contains({1, 12, 13, 14}, item.tipus)}" onclick="$('#filepicker').fileinput('upload');">Confirmar</span>
+													<button type="button" class="btn btn-success" th:if="${item.tipus == 3}" 
+															onclick="processPAMTable('submit');">
+														<i class="fas fa-check-circle"></i> Confirmar
+													</button>
 												</div>
 											</form>
 										</div>
@@ -376,6 +439,10 @@
 	<script th:src="@{/js/fileinput/js/locales/ca.js}" th:if="${#locale.language != 'es'}"></script>	
 	<script th:src="@{/js/confirmation/bootstrap-confirmation.js}"></script>
 	<script src="https://cdn.jsdelivr.net/npm/mermaid@11.3.0/dist/mermaid.min.js"></script>
+	<script src="https://unpkg.com/@popperjs/core@2"></script>
+	<script src="https://unpkg.com/tippy.js@6"></script>
+	<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/dist/tippy.css" />
+	<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/themes/light.css" />
 
   
   	<script th:inline="javascript" th:if="${#authentication.principal.isAdmin()}">
@@ -414,6 +481,8 @@
     	var tinyobjectresizing = false;
 		var tinypasteplain = false;
 		var tinypasteremovestyles = true;
+		const widget = document.getElementById("pdfWidget");
+		const preview = document.getElementById("pdfPreviewContainer");
     	
     	function tinyconfigure(editor){
 			
@@ -694,8 +763,93 @@
 		    btnOkLabel: 'Sí',
 		    btnCancelClass: 'btn btn-sm btn-danger',
 		    btnCancelLabel: 'No',
-		  });		
-		  		
+		  });	
+		  
+		if ($.fn.DataTable.isDataTable('#pamTable')) {
+			$('#pamTable').DataTable().destroy();
+		}
+
+		$('#pamTable').DataTable({
+			"searching": false,  
+			"ordering": false, 
+			"paging": false,    
+			"info": false,       
+			"responsive": true,
+			"autoWidth": false
+		});
+
+
+		var jsonPrueba = [
+			{"id":"RH2-1", "objetivo":"Implantar el Manual para la Evaluación de la actividad docente del profesorado(Programa DOCENTIA)", "origen":"SAIC / Informe Externo", "actividades":"Fases 1 a 6 de certificación", "responsable":"Unidad de Calidad / RRHH", "prioridad":"Alta", "cursoInicio":"Curso Inicio:2022", "cursoFin":"Curso fin: 2024", "indicadores":"Profesorado evaluado"," gradoEjecucion":"En desarrollo", "justificacion":"Faltan los trámites de la Fase 6."},
+			{"id":"RH2-2","objetivo":null, "origen":null,"actividades":null,"responsable":null,"prioridad":"Alta","cursoInicio":null,"cursoFin":"27/28","indicadores":null,"gradoEjecucion":"En desarrollo","justificacion":null}];
+
+		rebuildPAMTable(jsonPrueba);
+		
+		$('#pamTable').on('input', 'textarea', function() {
+			autoResize(this);
+		});
+		
+		if(widget) {
+			dragElement(widget);
+			
+			widget.ondblclick = function() {
+				togglePdfPreview();
+			};
+		}
+
+		$('#pamTable tbody tr').each(function() {
+			$('.curso-select-dinamico').html(generarOpcionesCursos());
+		});
+
+		$('#pamTable').on('dblclick', 'td textarea', function() {
+			const target = this;
+			const currentVal = $(target).val();
+
+			const editorHtml = `
+				<div class="p-2" style="width: 400px;">
+					<label class="small font-weight-bold">Editor rápido</label>
+					<textarea id="popoverEditor" class="form-control mb-2" rows="6">${currentVal}</textarea>
+					<div class="text-right">
+						<button type="button" id="cancelPop" class="btn btn-xs btn-light">Cancelar</button>
+						<button type="button" id="savePop" class="btn btn-xs btn-primary">Guardar</button>
+					</div>
+				</div>
+			`;
+
+			const instance = tippy(target, {
+				content: editorHtml,
+				allowHTML: true,
+				interactive: true,
+				trigger: 'manual',
+				placement: 'top',
+				theme: 'light',
+				maxWidth: 'none',
+				onShown(instance) {
+					$('#popoverEditor').focus();
+					
+					$('#savePop').on('click', (e) => {
+						e.preventDefault();
+						e.stopPropagation();
+						const newVal = $('#popoverEditor').val();
+						$(target).val(newVal);
+						autoResize(target);
+						instance.hide();
+					});
+
+
+					$('#cancelPop').on('click', (e) => {
+						e.preventDefault();
+						e.stopPropagation();
+						instance.hide();
+					});
+				},
+				onHidden(instance) {
+					instance.destroy(); 
+				}
+			});
+
+			instance.show();
+		});
 	});
 	
 	$('#customFile').on("change", function() {
@@ -898,7 +1052,282 @@
 		};
 		img.src = svgBase64;
 	}
-		
+
+	function addNewRowPAM() {
+		const tableBody = document.querySelector('#pamTable tbody');
+		const filas = tableBody.querySelectorAll('tr');
+		let nuevoId ="RH-1";
+
+		if (filas.length > 0) {}{
+			const ultimaFila = filas[filas.length - 1];
+			const ultimoIdTexto = ultimaFila.querySelector('td').innerText.trim();
+			const partes = ultimoIdTexto.match(/^(.*-)(\d+)$/);
+			
+			if (partes) {
+				const prefijo = partes[1];
+				const numero = parseInt(partes[2]) + 1; 
+				nuevoId = prefijo + numero.toString().padStart(2, '0');
+			}
+		}
+		const newRow = document.createElement('tr');
+		const opcionesDinamicas = generarOpcionesCursos();
+
+		newRow.innerHTML = `
+						<td><small>${nuevoId}</small></td>
+						<td><textarea class="form-control form-control-sm" rows="3" placeholder="Objetivo..."></textarea></td>
+						<td>
+							<select class="form-control form-control-sm">
+								<option>SAIC</option>
+								<option>Autoinforme</option>
+								<option>Informe Externo</option>
+							</select>
+						</td>
+						<td><textarea class="form-control form-control-sm" rows="3" placeholder="Actividades..."></textarea></td>
+						<td><textarea class="form-control form-control-sm" rows="2" placeholder="Responsable..."></textarea></td>
+						<td>
+							<select class="form-control form-control-sm">
+								<option>Alta</option>
+								<option>Media</option>
+								<option>Baja</option>
+							</select>
+						</td>
+						<td><select class="form-control form-control-sm">${opcionesDinamicas}</select></td>
+        				<td><select class="form-control form-control-sm">${opcionesDinamicas}</select></td>
+						<td><textarea class="form-control form-control-sm" rows="2" placeholder="Indicadores"></textarea></td>
+						<td>
+							<select class="form-control form-control-sm">
+								<option>Planificación</option>
+								<option>En desarrollo</option>
+								<option>Finalizado</option>
+								<option>Cancelada</option>
+							</select>
+						</td>
+						<td><textarea class="form-control form-control-sm" rows="2" placeholder="Justificación"></textarea></td>
+	`;
+
+		tableBody.appendChild(newRow);
+
+		newRow.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+	}
+
+	function autoResize(textarea) {
+		textarea.style.height = 'auto';
+		textarea.style.height = textarea.scrollHeight + 'px';
+	}
+
+	function dragElement(elmnt) {
+		let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
+		elmnt.onmousedown = dragMouseDown;
+
+		function dragMouseDown(e) {
+			e = e || window.event;
+			pos3 = e.clientX;
+			pos4 = e.clientY;
+			document.onmouseup = closeDragElement;
+			document.onmousemove = elementDrag;
+		}
+
+		function elementDrag(e) {
+			e = e || window.event;
+			e.preventDefault();
+			pos1 = pos3 - e.clientX;
+			pos2 = pos4 - e.clientY;
+			pos3 = e.clientX;
+			pos4 = e.clientY;
+			elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
+			elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
+			elmnt.style.right = 'auto'; 
+		}
+
+		function closeDragElement() {
+			document.onmouseup = null;
+			document.onmousemove = null;
+		}
+	}
+
+	function togglePdfPreview() {
+		const $preview = $("#pdfPreviewContainer");
+		const $widget = $("#pdfWidget");
+		const $tableContainer = $('.table-responsive'); 
+		const $table = $('#pamTable');
+
+		if ($preview.is(":hidden")) {
+			const isRight = $widget.offset().left > (window.innerWidth / 2);
+
+			$widget.fadeOut(200);
+
+			$preview.addClass('active-split');
+			
+			if (isRight) {
+				$preview.css({ left: 'auto', right: '0' });
+				$tableContainer.addClass('table-split-right').removeClass('table-split-left');
+			} else {
+				$preview.css({ left: '0', right: 'auto' });
+				$tableContainer.addClass('table-split-left').removeClass('table-split-right');
+			}
+
+			$table.addClass('compact-mode');
+			
+			$preview.fadeIn(300).css("display", "flex");
+
+			setTimeout(function() {
+				if ($.fn.DataTable.isDataTable('#pamTable')) {
+					$('#pamTable').DataTable().columns.adjust();
+				}
+			}, 310);
+		} else {
+			closePdfPreview();
+		}
+	}
+	
+	function closePdfPreview(event) {
+		if(event) {
+			event.preventDefault(); 
+			event.stopPropagation();
+		}
+		const $preview = $("#pdfPreviewContainer");
+		const $widget = $("#pdfWidget");
+		const $tableContainer = $('.table-responsive');
+		const $table = $('#pamTable');
+
+		$tableContainer.removeClass('table-split-right table-split-left');
+		$table.removeClass('compact-mode');
+		$preview.removeClass('active-split');
+
+		$preview.fadeOut(200, function() {
+			$widget.fadeIn(300);
+		});
+	}
+
+	function generarOpcionesCursos() {
+		const fechaActual = new Date();
+		const añoActual = fechaActual.getFullYear();
+		const mesActual = fechaActual.getMonth();
+
+		let cursoActual = (mesActual >= 7) ? añoActual : añoActual - 1;
+
+		let html = '<option value="">Seleccionar...</option>';
+
+		for (let i = -3; i <= 3; i++) {
+			let inicio = cursoActual + i;
+			let fin = inicio + 1;
+			let texto = `${inicio.toString().slice(-2)}/${fin.toString().slice(-2)}`;
+			html += `<option value="${texto}">${texto}</option>`;
+		}
+
+		return html;
+	}
+
+	function rebuildPAMTable(data) {
+		const tableBody = $('#pamTable tbody');
+		tableBody.empty();
+
+		if (!data || data.length === 0) return;
+
+		const renderInputOrStatic = function(value, placeholder, rows = 2) {
+			if (value === null || value === undefined || value === "" || value === "null") {
+				return `<textarea class="form-control form-control-sm" rows="${rows}" placeholder="${placeholder}"></textarea>`;
+			} else {
+				return `<small class="text-dark">${value}</small>`;
+			}
+		};
+
+		data.forEach(item => {
+			const row = $('<tr></tr>');
+
+			row.html(`
+				<td>
+					<small>${item.id || ''}</small>
+				</td>
+				<td>${renderInputOrStatic(item.objetivo, "Objetivo...", 3)}</td>
+				<td>
+					<select class="form-control form-control-sm">
+						<option value="SAIC" ${item.origen === 'SAIC' ? 'selected' : ''}>SAIC</option>
+						<option value="Autoinforme" ${item.origen === 'Autoinforme' ? 'selected' : ''}>Autoinforme</option>
+						<option value="Informe Externo" ${item.origen === 'Informe Externo' ? 'selected' : ''}>Informe Externo</option>
+					</select>
+				</td>
+				<td>${renderInputOrStatic(item.actividades, "Actividades...", 3)}</td>
+            	<td>${renderInputOrStatic(item.responsable, "Responsable...")}</td>
+				<td>
+					<select class="form-control form-control-sm">
+						<option value="Alta" ${item.prioridad === 'Alta' ? 'selected' : ''}>Alta</option>
+						<option value="Media" ${item.prioridad === 'Media' ? 'selected' : ''}>Media</option>
+						<option value="Baja" ${item.prioridad === 'Baja' ? 'selected' : ''}>Baja</option>
+					</select>
+				</td>
+				<td><select class="form-control form-control-sm curso-inicio-val">${generarOpcionesCursos()}</select></td>
+            	<td><select class="form-control form-control-sm curso-fin-val">${generarOpcionesCursos()}</select></td>
+				<td>${renderInputOrStatic(item.indicadores, "Indicadores...")}</td>
+				<td>
+					<select class="form-control form-control-sm">
+						<option value="Planificación" ${item.gradoEjecucion === 'Planificación' ? 'selected' : ''}>Planificación</option>
+						<option value="En desarrollo" ${item.gradoEjecucion === 'En desarrollo' ? 'selected' : ''}>En desarrollo</option>
+						<option value="Finalizado" ${item.gradoEjecucion === 'Finalizado' ? 'selected' : ''}>Finalizado</option>
+						<option value="Cancelada" ${item.gradoEjecucion === 'Cancelada' ? 'selected' : ''}>Cancelada</option>
+					</select>
+				</td>
+				<td>${renderInputOrStatic(item.justificacion, "Justificación...")}</td>
+			`);
+			tableBody.append(row);
+		});
+
+		tableBody.find('textarea').each(function() {
+			if (typeof autoResize === 'function') autoResize(this);
+		});
+	}
+
+	function processPAMTable(actionType) {
+		var data = [];
+		var rows = $('#pamTable tbody tr');
+
+		rows.each(function() {
+			var row = $(this);
+			
+		var getVal = function(cellIndex) {
+            var cell = row.find('td').eq(cellIndex);
+            var input = cell.find('textarea, select, input');
+            
+            if (input.length > 0) {
+                return input.val(); 
+            } else {
+                return cell.text().trim(); 
+            }
+        };
+			var rowData = {
+				"id":             getVal(0),
+				"objetivo":       getVal(1),
+				"origen":         getVal(2),
+				"actividades":    getVal(3),
+				"responsable":    getVal(4),
+				"prioridad":      getVal(5),
+				"cursoInicio":    getVal(6),
+				"cursoFin":       getVal(7),
+				"indicadores":    getVal(8),
+				"gradoEjecucion": getVal(9),
+				"justificacion":  getVal(10)
+			};
+
+			if (rowData.id !== "") {
+				data.push(rowData);
+			}
+		});
+
+		var jsonResult = JSON.stringify(data);
+		$('#pam_json_data').val(jsonResult);
+
+		if (actionType === 'draft') {
+			console.log("Generando Borrador JSON:", jsonResult);
+			alert("Borrador de la tabla generado correctamente en el sistema.");
+		} else {
+			if (data.length === 0) {
+				alert("La tabla está vacía. Por favor, añade al menos una acción.");
+				return false;
+			}
+			console.log("Enviando JSON definitivo:", jsonResult);
+		}
+	}
+				
 	</script>
 
 </body>