Commit 33a11167 by willgonzz

boolean para saber si existe una convocatoria abierta para cargo, eliminacion de…

boolean para saber si existe una convocatoria abierta para cargo, eliminacion de agregar convocatoria, agregar boton de abrir convocatoria en lista de cargos
parent 2f3104ce
...@@ -53,6 +53,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -53,6 +53,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.mvcMatchers("/home").authenticated() .mvcMatchers("/home").authenticated()
.mvcMatchers("/cargo*").authenticated() .mvcMatchers("/cargo*").authenticated()
.mvcMatchers("/convocatoria*").authenticated() .mvcMatchers("/convocatoria*").authenticated()
.mvcMatchers("/convocatoria/crear/*").authenticated()
.mvcMatchers("/tecnologia*").authenticated() .mvcMatchers("/tecnologia*").authenticated()
.mvcMatchers("/postulantes","/postulantes/**").authenticated() .mvcMatchers("/postulantes","/postulantes/**").authenticated()
.mvcMatchers("/edit-user-data").authenticated() .mvcMatchers("/edit-user-data").authenticated()
......
...@@ -62,12 +62,6 @@ public class ConvocatoriaController { ...@@ -62,12 +62,6 @@ public class ConvocatoriaController {
//model.addAttribute("convocatorias",cargoId==null? convoRepo.findAll() : convoRepo.findByCargoId(cargoId)); //model.addAttribute("convocatorias",cargoId==null? convoRepo.findAll() : convoRepo.findByCargoId(cargoId));
return "convocatorias"; return "convocatorias";
} }
@RequestMapping("/convocatoria")
public String formConvocatoria(Model model) {
model.addAttribute("cargos", cargoRepo.findAll());
model.addAttribute("convocatoria", new ConvocatoriaCargo());
return "convocatoria-form";
}
@PostMapping("/convocatoria") @PostMapping("/convocatoria")
public String guardarConvocatoria(@ModelAttribute ConvocatoriaCargo convocatoria, BindingResult result,RedirectAttributes redirectAttributes) { public String guardarConvocatoria(@ModelAttribute ConvocatoriaCargo convocatoria, BindingResult result,RedirectAttributes redirectAttributes) {
...@@ -84,7 +78,20 @@ public class ConvocatoriaController { ...@@ -84,7 +78,20 @@ public class ConvocatoriaController {
System.out.println(convocatoria.getFechaInicio()); System.out.println(convocatoria.getFechaInicio());
return "redirect:/convocatorias"; return "redirect:/convocatorias";
} }
@RequestMapping("/convocatoria/crear/{id}")
public String guardarConvocatoriaa(@PathVariable(required = false) Long id) {
ConvocatoriaCargo convocatoria=new ConvocatoriaCargo();
convocatoria.setCargo(cargoRepo.findByIdCargo(id));
convocatoria.setCargoId(cargoRepo.findByIdCargo(id).getId());
System.out.println(cargoRepo.findByIdCargo(id).getNombre());
convocatoria.setFechaInicio(new Date());
convocatoria.setEstado(EstadoConvocatoria.abierto);
convocatoria.getCargo().setExisteConvocatoria(true);
convoRepo.save(convocatoria);
System.out.println(convocatoria.getFechaInicio());
return "redirect:/convocatorias";
}
/* @RequestMapping("/convocatoria/{id}") /* @RequestMapping("/convocatoria/{id}")
public String formConvocatoria(Model model,@PathVariable(required = false) Long id) { public String formConvocatoria(Model model,@PathVariable(required = false) Long id) {
...@@ -111,6 +118,7 @@ public class ConvocatoriaController { ...@@ -111,6 +118,7 @@ public class ConvocatoriaController {
convocatoria=convoRepo.findByIdConvocatoriaCargo(id); convocatoria=convoRepo.findByIdConvocatoriaCargo(id);
convocatoria.setEstado(EstadoConvocatoria.cerrado); convocatoria.setEstado(EstadoConvocatoria.cerrado);
convocatoria.setFechaFin(new Date()); convocatoria.setFechaFin(new Date());
convocatoria.getCargo().setExisteConvocatoria(false);
convoRepo.save(convocatoria); convoRepo.save(convocatoria);
/*if(id != null) convocatoria.setId(id); /*if(id != null) convocatoria.setId(id);
//System.out.println(convoRepo.filtrarConvocatoriasPorCargo(convocatoria.getCargoId())); //System.out.println(convoRepo.filtrarConvocatoriasPorCargo(convocatoria.getCargoId()));
......
...@@ -30,6 +30,9 @@ public class Cargo { ...@@ -30,6 +30,9 @@ public class Cargo {
@JsonManagedReference @JsonManagedReference
private List<ConvocatoriaCargo> convocatorias; private List<ConvocatoriaCargo> convocatorias;
@Column(name = "existe_convocatoria")
boolean existeConvocatoria=false;
public List<ConvocatoriaCargo> getConvocatorias() { public List<ConvocatoriaCargo> getConvocatorias() {
return convocatorias; return convocatorias;
} }
...@@ -39,4 +42,13 @@ public class Cargo { ...@@ -39,4 +42,13 @@ public class Cargo {
public static Object values() { public static Object values() {
return null; return null;
} }
public boolean isExisteConvocatoria() {
return this.existeConvocatoria;
}
public void setExisteConvocatoria(boolean existeConvocatoria) {
this.existeConvocatoria = existeConvocatoria;
}
} }
...@@ -11,9 +11,10 @@ import org.springframework.data.jpa.repository.Query; ...@@ -11,9 +11,10 @@ import org.springframework.data.jpa.repository.Query;
public interface CargoRepository extends JpaRepository<Cargo,Long>{ public interface CargoRepository extends JpaRepository<Cargo,Long>{
public Page<Cargo> findByNombreContainingIgnoreCase(String nombre, Pageable pageable); public Page<Cargo> findByNombreContainingIgnoreCase(String nombre, Pageable pageable);
@Query(value = "SELECT c FROM Cargo c WHERE c.id=?1")
public Cargo findByIdCargo(Long id);
public boolean existsByNombreIgnoreCase(String nombre); public boolean existsByNombreIgnoreCase(String nombre);
public List<Cargo> findByexisteConvocatoriaFalse();
@Query(value = "SELECT * FROM cargo",nativeQuery = true) @Query(value = "SELECT * FROM cargo",nativeQuery = true)
public Page<Cargo> findAllCargo(Pageable pageable ); public Page<Cargo> findAllCargo(Pageable pageable );
} }
[ [
{ {
"id": 1, "id": 1,
"nombre": "dev java" "nombre": "dev java",
"existeConvocatoria":true
}, },
{ {
"id": 2, "id": 2,
"nombre": "dev php" "nombre": "dev php",
"existeConvocatoria":true
}, },
{ {
"id": 3, "id": 3,
"nombre": "dev python" "nombre": "dev python",
"existeConvocatoria":true
}, },
{ {
"id": 4, "id": 4,
"nombre": "dev c" "nombre": "dev c",
"existeConvocatoria":true
}, },
{ {
"id": 5, "id": 5,
"nombre": "dev android" "nombre": "dev android",
"existeConvocatoria":true
} }
] ]
\ No newline at end of file
...@@ -51,6 +51,11 @@ contentType="text/html;charset=UTF-8" language="java" %> ...@@ -51,6 +51,11 @@ contentType="text/html;charset=UTF-8" language="java" %>
> >
</td> </td>
<td><a href="/cargo/${cargo.id}">Editar cargo</a></td> <td><a href="/cargo/${cargo.id}">Editar cargo</a></td>
<td>
<c:if test="${!cargo.isExisteConvocatoria()}">
<a class="btn btn-secondary" href="/convocatoria/crear/${cargo.id}">abrirConvocatoria</a>
</c:if>
</td>
</tr> </tr>
</c:forEach> </c:forEach>
</tbody> </tbody>
......
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<layout:extends name="layouts/base.jsp">
<layout:put block="cssDeclaracion" type="APPEND"></layout:put>
<layout:put block="contents" type="REPLACE">
<h2>${convocatoria.id == null ? "Agregar" : "Modificar"} Convocatoria</h2>
<div class="p-3 mb-2 bg-light text-dark bg-transparent ">
<form:form action="/convocatoria/${convocatoria.id == null ? '' : convocatoria.id}" method="post" modelAttribute="convocatoria">
<div class="mb-3 col-3">
<form:label path="cargoId" class="form-label">Cargo</form:label>
<form:select class="form-select" path="cargoId">
<c:forEach items="${cargos}" var="cargo">
<form:option value="${cargo.id}">${cargo.nombre} </form:option>
</c:forEach>
</form:select>
</div>
<button type="submit" class="btn btn-primary">Abrir Convocatoria</button>
</form:form>
</div>
</layout:put>
<layout:put block="scripts" type="APPEND">
</layout:put>
</layout:extends>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<layout:extends name="layouts/base.jsp">
<layout:put block="contents" type="REPLACE">
<div id="element-to-print">
<h2 style="text-align: center;">
DETALLE POSTULANTE
</h2>
<div class="row gy-3">
<div class="col-md-6">
<div class="card mb-3">
<div class="card-body">
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Nombre</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.nombre} ${postulante.apellido}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Email</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.correo}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Vive en</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.getCiudad().getNombre()}, ${postulante.getCiudad().getDepartamento().getNombre()}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Nro de Documento</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.tipoDocumento}: ${postulante.nroDocument}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Telefono</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.telefono}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Edad</h6>
</div>
<div id="edad" class="col-sm-9 text-secondary"></div>
<input style="display: none;" id="dob" value="${postulante.fechaNacimiento}">
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Direccion</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.direccion}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Nivel de Ingles</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.nivelIngles}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Estado Civil</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.estadoCivil.getDescripcion()}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Nacionalidad</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.nacionalidad.getDescripcion()}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Disponbilidad</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.disponibilidad.getDescripcion()}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">Estado</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.estadoPostulante.getEstado()}
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<h6 class="mb-0">ComentarioRRHH</h6>
</div>
<div class="col-sm-9 text-secondary">
${postulante.getComentarioRRHH()}
</div>
</div>
<hr>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row gy-3">
<div class="col-md-6">
<div class="card h-100">
<div class="card-body">
<h6 class="text-start fw-bold">Tecnologias</h6>
<c:forEach items="${postulante.tecnologias}" var="detalle_tecnologia">
<small>${detalle_tecnologia.getTecnologia().getNombre()}</small>
<div class="progress mb-3" style="height: 5px">
<div class="progress-bar bg-primary" role="progressbar" style="width: ${(detalle_tecnologia.getNivel() / 5) * 100}%" aria-valuenow="${detalle_tecnologia.getNivel()}" aria-valuemin="1" aria-valuemax="5"></div>
</div>
</c:forEach>
<hr>
<h6 class="text-start fw-bold">Cargos al que postula</h6>
<ul class="list-group list-group-flush">
<c:forEach items="${postulante.postulaciones}" var="convocatoria">
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">${convocatoria.getCargo().getNombre()}</h6>
<span class="text-secondary"></span>
</li>
</c:forEach>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<div id="carouselExampleIndicators" class="carousel carousel-dark slide" data-bs-ride="carousel">
<div class="carousel-inner">
<h6 class="d-flex justify-content-between fw-bold px-1">
<c:choose>
<c:when test="${postulante.experiencias.size() > 1}">
<i class="bi bi-arrow-left-circle-fill" data-bs-target="#carouselExampleIndicators" data-bs-slide="prev"></i>
Experiencias
<i class="bi bi-arrow-right-circle-fill" data-bs-target="#carouselExampleIndicators" data-bs-slide="next"></i>
</c:when>
<c:otherwise>
Experiencias
</c:otherwise>
</c:choose>
</h6>
<c:forEach items="${postulante.experiencias}" var="detalle_experiencia" varStatus="status">
<div class="carousel-item ${status.first ? 'active' : ''}" data-bs-interval="false">
<ul class="list-group list-group-flush ">
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Institucion</h6>
<span class="text-secondary">${detalle_experiencia.getInstitucion()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Fecha Inicio</h6>
<span class="text-secondary"><fmt:formatDate value="${detalle_experiencia.getFechaDesde()}" pattern="dd-MM-yyyy" /></span>
<!-- <input style="display:none;" id="fechaInicioExp" value="${detalle_experiencia.getFechaDesde()}">
<span style="display: none;" class="text-secondary" id="fechaInicioExp2">${detalle_experiencia.getFechaDesde()}</span>-->
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Fecha Fin</h6>
<span class="text-secondary"><fmt:formatDate value="${detalle_experiencia.getFechaHasta()}" pattern="dd-MM-yyyy" /></span>
<!-- <input style="display:none;" id="fechaFinExp" value="${detalle_experiencia.getFechaHasta()}">
<span style="display: none;" class="text-secondary" id="fechaFinExp2">${detalle_experiencia.getFechaHasta()}</span>-->
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Referencia</h6>
<span class="text-secondary">${detalle_experiencia.getNombreReferencia()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Telefono de la referencia</h6>
<span class="text-secondary">${detalle_experiencia.getTelefonoReferencia()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Cargo</h6>
<span class="text-secondary">${detalle_experiencia.getCargo()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Motivo de salida</h6>
<span class="text-secondary">${detalle_experiencia.getMotivoSalida()}</span>
</li>
</ul>
</div>
</c:forEach>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<div id="carouselExampleIndicators1" class="carousel carousel-dark slide" data-bs-ride="carousel">
<div class="carousel-inner">
<h6 class="d-flex justify-content-between fw-bold px-1">
<c:choose>
<c:when test="${postulante.experiencias.size() > 1}">
<i class="bi bi-arrow-left-circle-fill" data-bs-target="#carouselExampleIndicators1" data-bs-slide="prev"></i>
Estudios
<i class="bi bi-arrow-right-circle-fill" data-bs-target="#carouselExampleIndicators1" data-bs-slide="next"></i>
</c:when>
<c:otherwise>
Estudios
</c:otherwise>
</c:choose>
</h6>
<c:forEach items="${postulante.estudios}" var="detalle_estudios" varStatus="status">
<div class="carousel-item ${status.first ? 'active' : ''}" data-bs-interval="false">
<ul class="list-group list-group-flush ">
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Institucion</h6>
<span class="text-secondary">${detalle_estudios.getInstitucion().getNombre()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Fecha Inicio</h6>
<span class="text-secondary"><fmt:formatDate value="${detalle_estudios.getFechaDesde()}" pattern="dd-MM-yyyy" /></span>
<!-- <input style="display:none;" id="fechaInicioEst" value="${detalle_estudios.getFechaDesde()}">-->
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Fecha Fin</h6>
<span class="text-secondary"><fmt:formatDate value="${detalle_estudios.getFechaHasta()}" pattern="dd-MM-yyyy" /></span>
<!-- <input style="display:none;" id="fechaFinEst" value="${detalle_estudios.getFechaHasta()}">-->
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Tipo de Estudio</h6>
<span class="text-secondary">${detalle_estudios.getTipoDeEstudio()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Tema de estudio</h6>
<span class="text-secondary">${detalle_estudios.getTemaDeEstudio()}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">Estado</h6>
<span class="text-secondary">${detalle_estudios.getEstado()}</span>
</li>
</ul>
</div>
</c:forEach>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h6 class="text-start fw-bold">Referencias Personales</h6>
<ul class="list-group list-group-flush">
<c:forEach items="${postulante.referencias}" var="referencia">
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap">
<h6 class="mb-0">${referencia.nombre}, ${referencia.relacion}, ${referencia.telefono}</h6>
<span class="text-secondary"></span>
</li>
</c:forEach>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="estadoModalLong" tabindex="-1" role="dialog" aria-labelledby="estadorrhhModal" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form:form class="needs-validation" method="post" modelAttribute="postulante">
<div class="modal-header">
<h5 class="modal-title" id="estadorrhhModal">Estado</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form:label path="estadoPostulante" class="form-label">Estado</form:label>
<div class="inputs">
<form:select class="form-select" path="estadoPostulante" aria-label="Default select example">
<c:forEach items="${estadoP}" var="estadoPostulante">
<c:choose>
<c:when test="${estadoPostulante.getEstado()=='Nuevo' }">
</c:when>
<c:otherwise>
<form:option value="${estadoPostulante}">${estadoPostulante.getEstado()}</form:option>
</c:otherwise>
</c:choose>
</c:forEach>
</form:select>
</div>
<div class="inputs">
<form:label path="comentarioRRHH" class="form-label">ComentarioRRHH</form:label>
<form:textarea class="form-control" path="comentarioRRHH" id="comentarioRRHH"></form:textarea>
</div><br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-primary" data-bs-dismiss="modal">Agregar</button>
</div>
</form:form>
</div>
</div>
</div>
</div>
<layout:put block="scripts" type="APPEND">
<script src="../valEdad.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js" integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var element = document.getElementById('element-to-print');
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'a1', orientation: 'portrait' }
};
html2pdf().set(opt).from(element).toPdf().save();
<%--location.replace("/postulantes/${postulante.id}/")--%>
</script>
</layout:put>
</layout:put>
</layout:extends>
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
</a> </a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="/cargo">Agregar Cargo</a></li> <li><a class="dropdown-item" href="/cargo">Agregar Cargo</a></li>
<li><a class="dropdown-item" href="/convocatoria">Agregar Convocatoria</a></li>
<li><a class="dropdown-item" href="/cargos">Listar cargos</a></li> <li><a class="dropdown-item" href="/cargos">Listar cargos</a></li>
<li><a class="dropdown-item" href="/convocatorias">Listar convocatorias</a></li> <li><a class="dropdown-item" href="/convocatorias">Listar convocatorias</a></li>
</ul> </ul>
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
</a> </a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="/cargo">Agregar Cargo</a></li> <li><a class="dropdown-item" href="/cargo">Agregar Cargo</a></li>
<li><a class="dropdown-item" href="/convocatoria">Agregar Convocatoria</a></li>
<li><a class="dropdown-item" href="/cargos">Listar cargos</a></li> <li><a class="dropdown-item" href="/cargos">Listar cargos</a></li>
<li><a class="dropdown-item" href="/convocatorias">Listar convocatorias</a></li> <li><a class="dropdown-item" href="/convocatorias">Listar convocatorias</a></li>
</ul> </ul>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment