Acabando con oepracion de borar,edit y crear en todas las entidades. Refactorizacion del codigo de metodos de paginacion a un metodo y un interfaz de paginacion. Refactorizacion de los scripts y cambios a css de una tablas. Quitando el id de las tabla que el usuario no necesita a verlos.

master
vicsash 5 months ago
parent dffe0bdbf0
commit ea6c8a7d63

@ -3,13 +3,9 @@ package com.example.proyectofinal.controllers;
import com.example.proyectofinal.models.empresas.*; import com.example.proyectofinal.models.empresas.*;
import com.example.proyectofinal.repositories.empresas.*; import com.example.proyectofinal.repositories.empresas.*;
import com.example.proyectofinal.servicios.ContactosService; import com.example.proyectofinal.servicios.*;
import com.example.proyectofinal.servicios.SectorService; import com.example.proyectofinal.servicios.implemetations.IPagination;
import com.example.proyectofinal.servicios.SucursalService;
import com.example.proyectofinal.servicios.implemetations.IEmpresa;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -28,25 +24,27 @@ public class BuscadorController {
@Autowired @Autowired
private EmpressaRepository empressaRepository; private EmpressaRepository empressaRepository;
@Autowired @Autowired
private AlumnoRepository alumnoRepository; private AlumnoService alumnoService;
@Autowired @Autowired
private OfertaRepository ofertaRepository; private OfertaService ofertasService;
@Autowired @Autowired
private SectorService sectorService; private SectorService sectorService;
@Autowired @Autowired
private SucursalService sucursalService; private SucursalService sucursalService;
@Autowired @Autowired
private SkillRepository skillRepository; private SkillService skillService;
@Autowired
private AlumnoRepository alumnoRepository;
@Autowired @Autowired
private ContactosService contactosService; private ContactosService contactosService;
@Autowired @Autowired
private FamiliaRepository familiaRepository; private FamiliaService familiaService;
@Autowired @Autowired
private CicloRepository cicloRepository; private CicloService cicloService;
@Autowired
private OfertaRepository ofertaRepository;
@Autowired @Autowired
private IEmpresa empresaService; private EmpresaService empresaService;
@GetMapping @GetMapping
public String buscador(){ public String buscador(){
@ -58,19 +56,16 @@ public class BuscadorController {
@RequestParam(defaultValue = "") String query, @RequestParam(defaultValue = "") String query,
Model model, Model model,
@RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortField, @RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir){ @RequestParam(defaultValue = "asc") String sortDir){
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50); List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) { if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
sortField = "id"; sortField = "nombre";
sortDir = "asc"; sortDir = "asc";
} }
Page<Empresa> page = this.empresaService.finadAllpaginated(pageNum, size, sortField, sortDir); Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, empresaService, itemsPage);
List<Empresa> empresas = page.getContent();
model.addAttribute("currentSize", size);
Map<String, Object> attributes = getPagAtrEmpresas(pageNum, query, size, sortField, sortDir, empresas, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) { for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue()); model.addAttribute(entry.getKey(), entry.getValue());
} }
@ -82,22 +77,18 @@ public class BuscadorController {
@RequestParam(defaultValue = "") String query, @RequestParam(defaultValue = "") String query,
Model model, Model model,
@RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortField, @RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir){ @RequestParam(defaultValue = "asc") String sortDir){
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50); List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) { if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
sortField = "id"; sortField = "nombre";
sortDir = "asc"; sortDir = "asc";
} }
Page<Sector> page = this.sectorService.finadAllpaginated(pageNum, size, sortField, sortDir); Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, sectorService, itemsPage);
List<Sector> sectors = page.getContent();
model.addAttribute("currentSize", size);
Map<String, Object> attributes = getPagAtrSetores(pageNum, query, size, sortField, sortDir, sectors, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) { for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue()); model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/sectores"; return "/list/sectores";
} }
@ -107,18 +98,15 @@ public class BuscadorController {
@RequestParam(defaultValue = "") String query, @RequestParam(defaultValue = "") String query,
Model model, Model model,
@RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortField, @RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir) { @RequestParam(defaultValue = "asc") String sortDir) {
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50); List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) { if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
sortField = "id"; sortField = "nombre";
sortDir = "asc"; sortDir = "asc";
} }
Page<Contacto> page = this.contactosService.finadAllpaginated(pageNum, size, sortField, sortDir); Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, contactosService, itemsPage);
List<Contacto> contactos = page.getContent();
model.addAttribute("currentSize", size);
Map<String, Object> attributes = getPagAtrContactos(pageNum, query, size, sortField, sortDir, contactos, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) { for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue()); model.addAttribute(entry.getKey(), entry.getValue());
} }
@ -130,141 +118,135 @@ public class BuscadorController {
@RequestParam(defaultValue = "") String query, @RequestParam(defaultValue = "") String query,
Model model, Model model,
@RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortField, @RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir){ @RequestParam(defaultValue = "asc") String sortDir){
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50); List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) { if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
sortField = "id"; sortField = "nombre";
sortDir = "asc"; sortDir = "asc";
} }
Page<Sucursal> page = this.sucursalService.finadAllpaginated(pageNum, size, sortField, sortDir); Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, sucursalService, itemsPage);
List<Sucursal> sucursals = page.getContent();
model.addAttribute("currentSize", size);
Map<String, Object> attributes = getPagAtrSucursales(pageNum, query, size, sortField, sortDir, sucursals, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) { for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue()); model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/sucursales"; return "/list/sucursales";
} }
public String searchAlumnosList(@RequestParam String query, @RequestParam String searchOption, @RequestParam(required = false) String filter, Model model, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
String[] word = query.split("\\b(y|o)\\b|[,/]");
if (word.length == 1 && word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todos")) {
List<Alumno> alumnos = new ArrayList<>(alumnoRepository.findAll());
model.addAttribute("alumnos", alumnos);
return "/list/alumnos";
}
return "/list/alumnos";
}
@GetMapping("/ofertas") @GetMapping("/ofertas/page/{pageNum}")
public String searchOfertasList(@RequestParam String query, @RequestParam String searchOption, @RequestParam(required = false) String filter, Model model, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size){ public String searchOfertasList(@PathVariable int pageNum,
Pageable pageable = PageRequest.of(page, size); @RequestParam(defaultValue = "") String query,
Model model,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir){
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
if (word.length == 1 && word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas")) { List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
List<Oferta> ofertas = new ArrayList<>(ofertaRepository.findAll()); if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
model.addAttribute("ofertas", ofertas); sortField = "nombre";
return "/list/ofertas"; sortDir = "asc";
}
Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, ofertasService, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/ofertas"; return "/list/ofertas";
} }
@GetMapping("/familias") @GetMapping("/familias/page/{pageNum}")
public String searchFamiliasList(@RequestParam String query, @RequestParam String searchOption, @RequestParam(required = false) String filter, Model model, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { public String searchFamiliasList(@PathVariable int pageNum,
Pageable pageable = PageRequest.of(page, size); @RequestParam(defaultValue = "") String query,
Model model,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir) {
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
if (word.length == 1 && word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas")) { List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
List<Familia> familias = new ArrayList<>(familiaRepository.findAll()); if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
model.addAttribute("familias", familias); sortField = "nombre";
return "/list/familias"; sortDir = "asc";
}
Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, familiaService, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/familias"; return "/list/familias";
} }
@GetMapping("/ciclos") @GetMapping("/ciclos/page/{pageNum}")
public String searchCiclosList(@RequestParam String query, @RequestParam String searchOption, @RequestParam(required = false) String filter, Model model, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { public String searchCiclosList(@PathVariable int pageNum,
Pageable pageable = PageRequest.of(page, size); @RequestParam(defaultValue = "") String query,
Model model,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir) {
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
if (word.length == 1 && word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas")) { List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
List<Ciclo> ciclos = new ArrayList<>(cicloRepository.findAll()); if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
model.addAttribute("ciclos", ciclos); sortField = "nombre";
return "/list/ciclos"; sortDir = "asc";
}
Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, cicloService, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/ciclos"; return "/list/ciclos";
} }
@GetMapping("/alumnos/page/{pageNum}")
public String searchAlumnosList(@PathVariable int pageNum,
@RequestParam(defaultValue = "") String query,
Model model,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "nombre") String sortField,
@RequestParam(defaultValue = "asc") String sortDir) {
@GetMapping("/skills")
public String searchSkillsList(@RequestParam String query, @RequestParam String searchOption, @RequestParam(required = false) String filter, Model model, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
String[] word = query.split("\\b(y|o)\\b|[,/]"); String[] word = query.split("\\b(y|o)\\b|[,/]");
if (word.length == 1 && word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas")) { List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
List<Skill> skills = new ArrayList<>(skillRepository.findAll()); if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
model.addAttribute("skills", skills); sortField = "nombre";
return "/list/skills"; sortDir = "asc";
} }
return "/list/skills"; Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, alumnoService, itemsPage);
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
model.addAttribute(entry.getKey(), entry.getValue());
} }
return "/list/alumnos";
public Map<String, Object> getPagAtrEmpresas(int pageNum, String query, int size, String sortField, String sortDir, List<Empresa> empresas, List<Integer> itemsPage) {
Map<String, Object> attributes = new HashMap<>();
Page<Empresa> page = this.empresaService.finadAllpaginated(pageNum, size, "id", "asc");
attributes.put("currentPage", pageNum);
attributes.put("totalPages", page.getTotalPages());
attributes.put("totalItems", page.getTotalElements());
attributes.put("sortField", sortField);
attributes.put("sortDir", sortDir);
attributes.put("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
attributes.put("empresas", empresas);
attributes.put("query", query);
attributes.put("itemsPage", itemsPage);
return attributes;
} }
public Map<String, Object> getPagAtrSetores(int pageNum, String query, int size, String sortField, String sortDir, List<Sector> sectors, List<Integer> itemsPage) { @GetMapping("/skills/page/{pageNum}")
Map<String, Object> attributes = new HashMap<>(); public String searchSkillsList(@PathVariable int pageNum,
Page<Sector> page = this.sectorService.finadAllpaginated(pageNum, size, "id", "asc"); @RequestParam(defaultValue = "") String query,
attributes.put("currentPage", pageNum); Model model,
attributes.put("totalPages", page.getTotalPages()); @RequestParam(defaultValue = "10") int size,
attributes.put("totalItems", page.getTotalElements()); @RequestParam(defaultValue = "nombre") String sortField,
attributes.put("sortField", sortField); @RequestParam(defaultValue = "asc") String sortDir) {
attributes.put("sortDir", sortDir); String[] word = query.split("\\b(y|o)\\b|[,/]");
attributes.put("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc"); List<Integer> itemsPage = Arrays.asList(5, 10, 15, 20, 25, 50);
attributes.put("sectores", sectors); if (word.length == 1 && (word[0].equalsIgnoreCase("all") || word[0].equalsIgnoreCase("todas"))) {
attributes.put("query", query); sortField = "nombre";
attributes.put("itemsPage", itemsPage); sortDir = "asc";
return attributes;
} }
Map<String, Object> attributes = getPaginatedAttributes(pageNum, query, size, sortField, sortDir, skillService, itemsPage);
public Map<String, Object> getPagAtrContactos(int pageNum, String query, int size, String sortField, String sortDir, List<Contacto> contactos, List<Integer> itemsPage) { for (Map.Entry<String, Object> entry : attributes.entrySet()) {
Map<String, Object> attributes = new HashMap<>(); model.addAttribute(entry.getKey(), entry.getValue());
Page<Contacto> page = this.contactosService.finadAllpaginated(pageNum, size, "id", "asc"); }
attributes.put("currentPage", pageNum); return "/list/skills";
attributes.put("totalPages", page.getTotalPages());
attributes.put("totalItems", page.getTotalElements());
attributes.put("sortField", sortField);
attributes.put("sortDir", sortDir);
attributes.put("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
attributes.put("contactos", contactos);
attributes.put("query", query);
attributes.put("itemsPage", itemsPage);
return attributes;
} }
public Map<String, Object> getPagAtrSucursales(int pageNum, String query, int size, String sortField, String sortDir, List<Sucursal> sucursals, List<Integer> itemsPage) { public <T> Map<String, Object> getPaginatedAttributes(int pageNum, String query, int size, String sortField, String sortDir, IPagination<T> service, List<Integer> itemsPage) {
Map<String, Object> attributes = new HashMap<>(); Map<String, Object> attributes = new HashMap<>();
Page<Sucursal> page = this.sucursalService.finadAllpaginated(pageNum, size, "id", "asc"); Page<T> page = service.findAllPaginated(pageNum, size, sortField, sortDir);
List<T> items = page.getContent();
attributes.put("currentPage", pageNum); attributes.put("currentPage", pageNum);
attributes.put("totalPages", page.getTotalPages()); attributes.put("totalPages", page.getTotalPages());
attributes.put("totalItems", page.getTotalElements()); attributes.put("totalItems", page.getTotalElements());
attributes.put("sortField", sortField); attributes.put("sortField", sortField);
attributes.put("sortDir", sortDir); attributes.put("sortDir", sortDir);
attributes.put("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc"); attributes.put("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
attributes.put("sucursales", sucursals); attributes.put("items", items);
attributes.put("query", query); attributes.put("query", query);
attributes.put("itemsPage", itemsPage); attributes.put("itemsPage", itemsPage);
attributes.put("currentSize", size);
return attributes; return attributes;
} }
@ -292,4 +274,55 @@ public class BuscadorController {
return ResponseEntity.ok(sucursals); return ResponseEntity.ok(sucursals);
} }
@GetMapping("/familias/search")
public ResponseEntity<List<Familia>> searchFamilias(@RequestParam String query) {
List<Familia> familias = familiaService.search(query);
return ResponseEntity.ok(familias);
}
@GetMapping("/ciclos/search")
public ResponseEntity<List<Ciclo>> searchCiclos(@RequestParam String query) {
List<Ciclo> ciclos = cicloService.search(query);
return ResponseEntity.ok(ciclos);
}
@GetMapping("/skills/search")
public ResponseEntity<List<Skill>> searchSkills(@RequestParam String query) {
List<Skill> ciclos = skillService.search(query);
return ResponseEntity.ok(ciclos);
}
@GetMapping("/alumnos/search")
public ResponseEntity<List<Alumno>> searchAlumnos(@RequestParam String query) {
List<Alumno> alumnos = alumnoService.search(query);
for (Alumno alumno : alumnos) {
List<Object[]> skillsData = alumnoRepository.findSkillsByAlumnoId(alumno.getId());
Set<Skill> skills = new HashSet<>();
for (Object[] skillData : skillsData) {
Skill skill = new Skill();
skill.setId((Long) skillData[0]);
skill.setNombre((String) skillData[1]);
skills.add(skill);
}
alumno.setSkills(skills);
}
return ResponseEntity.ok(alumnos);
}
@GetMapping("/ofertas/search")
public ResponseEntity<List<Oferta>> searchOfertas(@RequestParam String query) {
List<Oferta> ofertas = ofertasService.search(query);
for (Oferta oferta : ofertas) {
List<Object[]> skillsData = ofertaRepository.findSkillsByOfertaId(oferta.getId());
Set<Skill> skills = new HashSet<>();
for (Object[] skillData : skillsData) {
Skill skill = new Skill();
skill.setId((Long) skillData[0]);
skill.setNombre((String) skillData[1]);
skills.add(skill);
}
oferta.setSkills(skills);
}
return ResponseEntity.ok(ofertas);
}
} }

@ -0,0 +1,92 @@
package com.example.proyectofinal.controllers.modelControllers;
import com.example.proyectofinal.models.empresas.*;
import com.example.proyectofinal.servicios.AlumnoService;
import com.example.proyectofinal.servicios.CicloService;
import com.example.proyectofinal.servicios.SkillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
@Controller
@RequestMapping()
public class AlumnoController {
@Autowired
private AlumnoService alumnoService;
@Autowired
private SkillService skillService;
@Autowired
private CicloService cicloService;
@GetMapping("/admin/alumno/create")
public String showCreateForm(Model model) {
Alumno alumno = new Alumno();
List<Ciclo> ciclos = cicloService.findAll();
List<Skill> skills = skillService.findAll();
model.addAttribute("skills", skills);
model.addAttribute("alumno", alumno);
model.addAttribute("ciclos", ciclos);
return "admin/alumno/create";
}
@PostMapping("/alumno/save")
public ResponseEntity<String> saveAlumno(Alumno alumno, @RequestParam("ciclo") Long ciclo, @RequestParam("skills") List<Long> skills){
try{
Ciclo cicloEntity = cicloService.findById(ciclo);
Set<Skill> skillEntities = skillService.findAllByIds(skills);
alumno.setCiclo(cicloEntity);
alumno.setSkills(skillEntities);
Alumno testIfExist = alumnoService.exists(alumno);
if(testIfExist != null){
return new ResponseEntity<>("El alumno ya existe", HttpStatus.BAD_REQUEST);
}
alumnoService.save(alumno);
return new ResponseEntity<>("El alumno fue guardado con exito", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/admin/alumno/update/{id}")
public String showUpdateForm(Model model, @PathVariable Long id) {
Alumno alumno = alumnoService.findById(id);
List<Ciclo> ciclos = cicloService.findAll();
List<Skill> skills = skillService.findAll();
model.addAttribute("skills", skills);
model.addAttribute("alumno", alumno);
model.addAttribute("ciclos", ciclos);
return "admin/alumno/update";
}
@PostMapping("/alumno/update")
public ResponseEntity<String> updateAlumno(Alumno alumno, @RequestParam("ciclo") Long ciclo, @RequestParam("skills") List<Long> skills){
try{
Ciclo cicloEntity = cicloService.findById(ciclo);
Set<Skill> skillEntities = skillService.findAllByIds(skills);
alumno.setCiclo(cicloEntity);
alumno.setSkills(skillEntities);
alumnoService.save(alumno);
return new ResponseEntity<>("El alumno fue actualizado con exito", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/alumno/delete/{id}")
public ResponseEntity<String> deleteAlumno(@PathVariable Long id){
try{
alumnoService.deleteById(id);
return new ResponseEntity<>("El alumno ha sido eliminado", HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

@ -0,0 +1,87 @@
package com.example.proyectofinal.controllers.modelControllers;
import com.example.proyectofinal.models.empresas.Ciclo;
import com.example.proyectofinal.models.empresas.Familia;
import com.example.proyectofinal.servicios.CicloService;
import com.example.proyectofinal.servicios.FamiliaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping()
public class CicloController {
@Autowired
private CicloService cicloService;
@Autowired
private FamiliaService familiaService;
@GetMapping("/admin/ciclo/create")
public String showCreateForm(Model model) {
Ciclo ciclo = new Ciclo();
List<Familia> familias = familiaService.findAll();
Familia familia = new Familia();
model.addAttribute("ciclo", ciclo);
model.addAttribute("familias", familias);
model.addAttribute("familia", familia);
return "admin/ciclo/create";
}
@PostMapping("/ciclo/save")
public ResponseEntity<String> saveCiclo(Ciclo ciclo, @RequestParam("familia") Long familiaId){
try{
Familia familia = familiaService.findById(familiaId);
ciclo.setFamilia(familia);
if(cicloService.exists(ciclo) != null){
return new ResponseEntity<>("Este ciclo ya existe en la base de datos", HttpStatus.BAD_REQUEST);
}else{
cicloService.save(ciclo);
return new ResponseEntity<>("El ciclo fue guardado con exito", HttpStatus.OK);
}
}catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/admin/ciclo/update/{id}")
public String showUpdateForm(Model model, @PathVariable Long id) {
Ciclo ciclo = cicloService.findById(id);
List<Familia> familias = familiaService.findAll();
Familia familia = new Familia();
model.addAttribute("ciclo", ciclo);
model.addAttribute("familias", familias);
model.addAttribute("familia", familia);
return "admin/ciclo/update";
}
@PostMapping("/ciclo/update")
public ResponseEntity<String> updateCiclo(Ciclo ciclo, @RequestParam("familia.id") Long familiaId){
try{
Familia familia = familiaService.findById(familiaId);
ciclo.setFamilia(familia);
cicloService.save(ciclo);
return new ResponseEntity<>("Los datos del ciclo fue renovados con exito", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/ciclo/delete/{id}")
public ResponseEntity<String> deleteCiclo(@PathVariable Long id){
try{
cicloService.deleteById(id);
return new ResponseEntity<>("El ciclo ha sido eliminado", HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

@ -1,44 +1,65 @@
package com.example.proyectofinal.controllers.modelControllers; package com.example.proyectofinal.controllers.modelControllers;
import com.example.proyectofinal.models.empresas.Ciclo; import com.example.proyectofinal.models.empresas.Familia;
import com.example.proyectofinal.repositories.empresas.CicloRepository;
import com.example.proyectofinal.servicios.FamiliaService; import com.example.proyectofinal.servicios.FamiliaService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashSet;
import java.util.Set;
@Controller @Controller
@RequestMapping("/familia") @RequestMapping()
public class FamiliaController { public class FamiliaController {
@Autowired
private CicloRepository cicloRepository;
@Autowired @Autowired
private FamiliaService familiaService; private FamiliaService familiaService;
@PostMapping("/crearFamilia") @GetMapping("/admin/familia/create")
@ResponseBody public String showCreateForm(Model model) {
public String editFamilia(@RequestParam String name) { Familia familia = new Familia();
String result = familiaService.createFamilia(name); model.addAttribute("familia", familia);
System.out.println(name); return "admin/familia/create";
if (result.equals("Familia creada")) { }
return "redirect:/editMain";
}else if (result.equals("Familia ya existe")){ @PostMapping("/familia/save")
return result; public ResponseEntity<String> saveFamilia(Familia familia){
try{
if(familiaService.findByName(familia.getNombre()) != null){
System.out.println("Este familia ya existe en la base de datos");
return new ResponseEntity<>("Este familia ya existe en la base de datos", HttpStatus.BAD_REQUEST);
}else { }else {
return "redirect:/error"; familiaService.save(familia);
return new ResponseEntity<>("La familia fue guardado con exito", HttpStatus.OK);
} }
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/admin/familia/update/{id}")
public String showUpdateForm(Model model, @PathVariable Long id) {
Familia familia = familiaService.findById(id);
model.addAttribute("familia", familia);
return "admin/familia/update";
} }
@PostMapping("/familia/update")
public ResponseEntity<String> updateFamilia(Familia familia){
try{
familiaService.save(familia);
return new ResponseEntity<>("La familia ha sido actualizado con exito", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/{id}") @GetMapping("/familia/delete/{id}")
public String getFamiliaById(@PathVariable Long id, Model model) { public ResponseEntity<String> deleteFamilia(@PathVariable Long id){
Set<Ciclo> cicloSet = new HashSet<>(cicloRepository.findCicloByFamiliaId(id)); try{
model.addAttribute("ciclos", cicloSet); familiaService.deleteById(id);
return "ciclo"; return new ResponseEntity<>("La familia ha sido eliminado", HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
} }
} }

@ -0,0 +1,107 @@
package com.example.proyectofinal.controllers.modelControllers;
import com.example.proyectofinal.models.empresas.*;
import com.example.proyectofinal.servicios.CicloService;
import com.example.proyectofinal.servicios.OfertaService;
import com.example.proyectofinal.servicios.SkillService;
import com.example.proyectofinal.servicios.SucursalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Controller
@RequestMapping()
public class OfertaController {
@Autowired
private OfertaService ofertaService;
@Autowired
private SkillService skillService;
@Autowired
private SucursalService sucursalService;
@Autowired
private CicloService cicloService;
@GetMapping("/admin/oferta/create")
public String showCreateForm(Model model) {
Oferta oferta = new Oferta();
List<Ciclo> ciclos = cicloService.findAll();
List<Skill> skills = skillService.findAll();
List<Sucursal> sucursals = sucursalService.findAll();
model.addAttribute("sucursals", sucursals);
model.addAttribute("skills", skills);
model.addAttribute("oferta", oferta);
model.addAttribute("ciclos", ciclos);
return "admin/oferta/create";
}
@PostMapping("/oferta/save")
public ResponseEntity<String> saveOferta(Oferta oferta, @RequestParam("ciclo") Long ciclo, @RequestParam("sucursal") Long sucursal, @RequestParam("skills") List<Long> skills){
try{
Ciclo cicloEntity = cicloService.findById(ciclo);
Sucursal sucursalEntity = sucursalService.findById(sucursal);
Set<Skill> skillEntities = skillService.findAllByIds(skills);
oferta.setCiclo(cicloEntity);
oferta.setSucursal(sucursalEntity);
oferta.setSkills(skillEntities);
Oferta testIfExist = ofertaService.findByName(oferta.getNombre());
if(testIfExist != null){
return new ResponseEntity<>("Esta oferta ya existe en la base de datos", HttpStatus.BAD_REQUEST);
}else {
ofertaService.save(oferta);
return new ResponseEntity<>("La oferta fue guadada con exito", HttpStatus.OK);
}
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/admin/oferta/update/{id}")
public String showUpdateForm(Model model, @PathVariable Long id) {
Oferta oferta = ofertaService.findById(id);
List<Ciclo> ciclos = cicloService.findAll();
List<Skill> skills = skillService.findAll();
List<Sucursal> sucursals = sucursalService.findAll();
model.addAttribute("sucursals", sucursals);
model.addAttribute("skills", skills);
model.addAttribute("oferta", oferta);
model.addAttribute("ciclos", ciclos);
return "admin/oferta/update";
}
@PostMapping("/oferta/update")
public ResponseEntity<String> updateOferta(Oferta oferta, @RequestParam("ciclo") Long ciclo, @RequestParam("sucursal") Long sucursal, @RequestParam("skills") List<Long> skills){
System.out.println("UPDATE TEST");
try{
Ciclo cicloEntity = cicloService.findById(ciclo);
Sucursal sucursalEntity = sucursalService.findById(sucursal);
Set<Skill> skillEntities = skillService.findAllByIds(skills);
oferta.setCiclo(cicloEntity);
oferta.setSucursal(sucursalEntity);
oferta.setSkills(skillEntities);
ofertaService.save(oferta);
return new ResponseEntity<>("La oferta fue guadada con exito", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/oferta/delete/{id}")
public ResponseEntity<String> deleteOferta(@PathVariable Long id){
try{
ofertaService.deleteById(id);
return new ResponseEntity<>("La oferta ha sido eliminado", HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

@ -0,0 +1,65 @@
package com.example.proyectofinal.controllers.modelControllers;
import com.example.proyectofinal.models.empresas.Skill;
import com.example.proyectofinal.servicios.SkillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping()
public class SkillController {
@Autowired
private SkillService skillService;
@GetMapping("/admin/skill/create")
public String showCreateForm(Model model) {
Skill skill = new Skill();
model.addAttribute("skill", skill);
return "admin/skill/create";
}
@PostMapping("/skill/save")
public ResponseEntity<String> saveSkill(Skill skill){
try{
if(skillService.findByName(skill.getNombre()) != null){
return new ResponseEntity<>("Este skill ya existe en la base de datos", HttpStatus.BAD_REQUEST);
}else {
skillService.save(skill);
return new ResponseEntity<>("El skill fue guardado con exito", HttpStatus.OK);
}
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/admin/skill/update/{id}")
public String showUpdateForm(Model model, @PathVariable Long id) {
Skill skill = skillService.findById(id);
model.addAttribute("skill", skill);
return "admin/skill/update";
}
@PostMapping("/skill/update")
public ResponseEntity<String> updateSkill(Skill skill){
try{
skillService.save(skill);
return new ResponseEntity<>("El skill fue renovado", HttpStatus.OK);
}catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/skill/delete/{id}")
public ResponseEntity<String> deleteSkill(@PathVariable Long id){
try{
skillService.deleteById(id);
return new ResponseEntity<>("Skill ha sido eliminada", HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

@ -1,6 +1,7 @@
package com.example.proyectofinal.models.empresas; package com.example.proyectofinal.models.empresas;
import jakarta.persistence.*; import jakarta.persistence.*;
import jdk.jfr.Name;
import lombok.*; import lombok.*;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@ -34,7 +35,8 @@ public class Alumno {
@NonNull @NonNull
@DateTimeFormat(pattern = "yyyy-mm-dd") @DateTimeFormat(pattern = "yyyy-mm-dd")
private Date fechaNacimiento; @Name("fecha_nacimiento")
private String fechaNacimiento;
@NonNull @NonNull
@Column(length = 45) @Column(length = 45)
@ -79,4 +81,5 @@ public class Alumno {
@JoinColumn(name = "fk_ciclo",referencedColumnName = "id") @JoinColumn(name = "fk_ciclo",referencedColumnName = "id")
@OnDelete(action = OnDeleteAction.CASCADE) @OnDelete(action = OnDeleteAction.CASCADE)
private Ciclo ciclo; private Ciclo ciclo;
} }

@ -25,6 +25,7 @@ public class Oferta {
@Column(length = 70) @Column(length = 70)
private String nombre; private String nombre;
//TODO see the order of elements //TODO see the order of elements
@NonNull @NonNull
@DateTimeFormat(pattern = "yyyy-mm-dd") @DateTimeFormat(pattern = "yyyy-mm-dd")
private String fecha; private String fecha;

@ -8,6 +8,7 @@ import lombok.NonNull;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
import java.util.Objects;
import java.util.Set; import java.util.Set;
@Entity @Entity
@ -30,4 +31,16 @@ public class Skill {
@ManyToMany(mappedBy = "skills") @ManyToMany(mappedBy = "skills")
private Set<Oferta> ofertas; private Set<Oferta> ofertas;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Skill skill = (Skill) o;
return id == skill.id;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
} }

@ -3,12 +3,40 @@ package com.example.proyectofinal.repositories.empresas;
import com.example.proyectofinal.models.empresas.Alumno; import com.example.proyectofinal.models.empresas.Alumno;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public interface AlumnoRepository extends JpaRepository<Alumno, Long> { public interface AlumnoRepository extends JpaRepository<Alumno, Long> {
@Query("Delete from Alumno a where a.ciclo.id = ?1")
void deleteByCiclo(Long id);
@Query("SELECT a FROM Alumno a WHERE a.ciclo.id = ?1")
List<Alumno> findByCiclo(Long id);
@Modifying
@Query(value = "DELETE FROM alumno_skill WHERE fk_alumno = ?1", nativeQuery = true)
void deleteSkillByAlumnoId(Long id);
@Query(value = "Select s.* from skills s " +
"inner join oferta_skill os on s.id = os.fk_skills " +
"where os.fk_oferta =?1", nativeQuery = true)
List<Object[]> findSkillsByAlumnoId(long id);
@Query("SELECT a FROM Alumno a JOIN a.skills s WHERE a.nombre LIKE %:query% OR a.apellido " +
"LIKE %:query% OR a.apellido2 LIKE %:query% OR a.correo LIKE %:query% OR a.correo2 " +
"LIKE %:query% OR a.nacionalidad LIKE %:query% OR a.genero LIKE %:query% OR a.dni " +
"LIKE %:query% OR a.nia LIKE %:query% OR s.nombre LIKE %:query%")
List<Alumno> search(String query);
@Query("SELECT a FROM Alumno a WHERE a.nia = ?1")
Alumno findByNia(String nia);
// @Query(value = "SELECT * FROM alumnos u WHERE MATCH(u.nombre, u.keywords, " + // @Query(value = "SELECT * FROM alumnos u WHERE MATCH(u.nombre, u.keywords, " +
// "u.apellido, u.apellido2, u.correo, u.correo2, u.nacionalidad, u.genero, u.dni, u.nia ) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true) // "u.apellido, u.apellido2, u.correo, u.correo2, u.nacionalidad, u.genero, u.dni, u.nia ) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true)
// public ArrayList<Alumno> getAlumnoByKeywordsOrName(String keyword1); // public ArrayList<Alumno> getAlumnoByKeywordsOrName(String keyword1);

@ -6,12 +6,16 @@ import org.springframework.data.jpa.repository.Query;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public interface CicloRepository extends JpaRepository<Ciclo, Long> { public interface CicloRepository extends JpaRepository<Ciclo, Long> {
// @Query(value = "SELECT * FROM ciclos u WHERE MATCH(u.nombre, u.familias) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true) // @Query(value = "SELECT * FROM ciclos u WHERE MATCH(u.nombre, u.familias) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true)
// public Ciclo getCicloByKeywordsOrName(String keyword1); // public Ciclo getCicloByKeywordsOrName(String keyword1);
@Query(value = "Select * from ciclos c where c.familia_id = ?1", nativeQuery = true) @Query("SELECT c FROM Ciclo c WHERE c.familia.id = :id")
public ArrayList<Ciclo> findCicloByFamiliaId(Long id); List<Ciclo> findCicloByFamiliaId(Long id);
@Query("SELECT c FROM Ciclo c WHERE c.nombre LIKE %?1% or c.familia.nombre LIKE %?1% or c.codigo LIKE %?1%")
List<Ciclo> search(String query);
} }

@ -25,7 +25,7 @@ public interface ContactoRepository extends JpaRepository<Contacto, Long> {
@Query(value="SELECT * FROM contactos c WHERE nombre= ?1 and apellido = ?2 and apellido2 =?3", nativeQuery = true) @Query(value="SELECT * FROM contactos c WHERE nombre= ?1 and apellido = ?2 and apellido2 =?3", nativeQuery = true)
Contacto existsByNombreApe(String nombre, String apellido, String apellido2); Contacto existsByNombreApe(String nombre, String apellido, String apellido2);
@Query("SELECT c FROM Contacto c WHERE c.nombre LIKE %:query% OR c.apellido LIKE %:query% OR c.apellido2 LIKE %:query% OR c.correo LIKE %:query% OR c.telefono LIKE %:query% OR c.empresa.nombre LIKE %:query% OR CAST(c.id AS string) = :query") @Query("SELECT c FROM Contacto c WHERE c.nombre LIKE %:query% OR c.apellido LIKE %:query% OR c.apellido2 LIKE %:query% OR c.correo LIKE %:query% OR c.telefono LIKE %:query% OR c.empresa.nombre LIKE %:query%")
List<Contacto> search(@Param("query") String query); List<Contacto> search(@Param("query") String query);
@Modifying @Modifying

@ -24,7 +24,7 @@ public interface EmpressaRepository extends JpaRepository<Empresa, Long>, JpaSpe
@Query(value = "SELECT * FROM empresas order by id Asc", nativeQuery = true) @Query(value = "SELECT * FROM empresas order by id Asc", nativeQuery = true)
List<Empresa> findAllAsc(); List<Empresa> findAllAsc();
@Query("SELECT e FROM Empresa e WHERE e.nombre LIKE %:query% OR e.cif LIKE %:query% OR e.correo LIKE %:query% OR e.telefono LIKE %:query% OR e.keywords LIKE %:query% OR e.sector.nombre LIKE %:query% OR CAST(e.id AS string) = :query") @Query("SELECT e FROM Empresa e WHERE e.nombre LIKE %:query% OR e.cif LIKE %:query% OR e.correo LIKE %:query% OR e.telefono LIKE %:query% OR e.keywords LIKE %:query% OR e.sector.nombre LIKE %:query%")
List<Empresa> search(@Param("query") String query); List<Empresa> search(@Param("query") String query);
@Query("SELECT e FROM Empresa e WHERE e.cif = :cif") @Query("SELECT e FROM Empresa e WHERE e.cif = :cif")

@ -1,9 +1,12 @@
package com.example.proyectofinal.repositories.empresas; package com.example.proyectofinal.repositories.empresas;
import com.example.proyectofinal.models.empresas.Familia; import com.example.proyectofinal.models.empresas.Familia;
import com.example.proyectofinal.models.empresas.Sector;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface FamiliaRepository extends JpaRepository<Familia, Long> { public interface FamiliaRepository extends JpaRepository<Familia, Long> {
@ -12,4 +15,7 @@ public interface FamiliaRepository extends JpaRepository<Familia, Long> {
@Query(value = "SELECT * FROM familias u WHERE MATCH(u.nombre) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true) @Query(value = "SELECT * FROM familias u WHERE MATCH(u.nombre) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true)
Optional<Object> findByName(String name); Optional<Object> findByName(String name);
@Query("SELECT f FROM Familia f WHERE f.nombre LIKE %:query%")
List<Familia> search(@Param("query") String query);
} }

@ -4,8 +4,8 @@ import com.example.proyectofinal.models.empresas.Oferta;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public interface OfertaRepository extends JpaRepository<Oferta, Long> { public interface OfertaRepository extends JpaRepository<Oferta, Long> {
@ -16,12 +16,29 @@ public interface OfertaRepository extends JpaRepository<Oferta, Long> {
@Query(value="Select * from ofertas where fk_sucursal = ?1", nativeQuery = true) @Query(value="Select * from ofertas where fk_sucursal = ?1", nativeQuery = true)
public List<Oferta> findBySucursalId(Long id); public List<Oferta> findBySucursalId(Long id);
@Query(value="Select * from ofertas where fk_ciclo = ?1", nativeQuery = true) @Query("Select o from Oferta o where o.ciclo.id = ?1")
public List<Oferta> findBySCiclolId(Long id); List<Oferta> findByCiclold(Long id);
@Modifying @Modifying
@Query(value = "DELETE FROM oferta_skill WHERE fk_oferta = ?1", nativeQuery = true) @Query(value = "DELETE FROM oferta_skill " +
"WHERE fk_oferta = ?1", nativeQuery = true)
void deleteSkillsByOfertaId(Long id); void deleteSkillsByOfertaId(Long id);
@Query(value = "SELECT s.* FROM skills s INNER JOIN " +
"oferta_skill os ON s.id = os.fk_skills " +
"WHERE os.fk_oferta = ?1", nativeQuery = true)
public List<Object[]> findSkillsByOfertaId(Long id);
@Query("SELECT o FROM Oferta o JOIN o.skills s " +
"WHERE o.nombre LIKE %:query% OR o.descripcion " +
"LIKE %:query% OR o.fecha LIKE %:query% " +
"OR o.sucursal.nombre LIKE %:query% " +
"OR o.ciclo.nombre LIKE %:query% OR s.nombre " +
"LIKE %:query%")
List<Oferta> search(@Param("query") String query);
@Query("SELECT o FROM Oferta o WHERE o.nombre = :name")
Oferta findByNombre(String name);
} }

@ -13,7 +13,7 @@ public interface SectorRepository extends JpaRepository<Sector, Long> {
Sector findByNombre(String nombre); Sector findByNombre(String nombre);
@Query("SELECT s FROM Sector s WHERE s.nombre LIKE %:query% OR CAST(s.id AS string) LIKE %:query%") @Query("SELECT s FROM Sector s WHERE s.nombre LIKE %:query% ")
List<Sector> search(@Param("query") String query); List<Sector> search(@Param("query") String query);
// @Query(value = "SELECT * FROM sectores u WHERE MATCH(u.nombre) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true) // @Query(value = "SELECT * FROM sectores u WHERE MATCH(u.nombre) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true)

@ -2,15 +2,24 @@ package com.example.proyectofinal.repositories.empresas;
import com.example.proyectofinal.models.empresas.Skill; import com.example.proyectofinal.models.empresas.Skill;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public interface SkillRepository extends JpaRepository<Skill, Long> { public interface SkillRepository extends JpaRepository<Skill, Long> {
// @Query(value = "SELECT * FROM skills u WHERE MATCH(u.nombre) AGAINST(?1 IN BOOLEAN MODE)", nativeQuery = true) @Query("SELECT s FROM Skill s WHERE s.nombre LIKE %:query%")
// public ArrayList<Skill> getSkillFullTextSeach(String word); List<Skill> search(String query);
@Modifying
@Query(value = "DELETE FROM oferta_skill WHERE fk_skills = ?1", nativeQuery = true)
void deleteSkillOferta(Long id);
@Modifying
@Query(value = "DELETE FROM alumno_skill WHERE fk_skills = ?1", nativeQuery = true)
void deleteSkillAlumno(Long id);
} }

@ -0,0 +1,80 @@
package com.example.proyectofinal.servicios;
import com.example.proyectofinal.models.empresas.Alumno;
import com.example.proyectofinal.repositories.empresas.AlumnoRepository;
import com.example.proyectofinal.servicios.implemetations.IAlumno;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class AlumnoService implements IAlumno{
@Autowired
private AlumnoRepository alumnoRepository;
@Override
public List<Alumno> findAll() {
return alumnoRepository.findAll();
}
@Override
public Page<Alumno> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNum - 1,pageSize,sort);
return this.alumnoRepository.findAll(pageable);
}
@Override
public Alumno findById(Long id) {
return alumnoRepository.findById(id).orElse(null);
}
@Override
public Alumno findByName(String name) {
return null;
}
@Override
public Alumno save(Alumno alumno) {
return alumnoRepository.save(alumno);
}
@Transactional
@Override
public void deleteById(Long id) {
Alumno alumno = alumnoRepository.findById(id).orElse(null);
if(alumno != null){
alumnoRepository.deleteSkillByAlumnoId(alumno.getId());
alumnoRepository.deleteById(id);
}
}
@Override
public List<Alumno> search(String query) {
return alumnoRepository.search(query);
}
@Override
public Alumno exists(Alumno alumno) {
return alumnoRepository.findByNia(alumno.getNia());
}
@Transactional
@Override
public void deleteByCiclo(Long id) {
List<Alumno> alumnos = alumnoRepository.findByCiclo(id);
if(!alumnos.isEmpty()){
for(Alumno alumno : alumnos){
System.out.println("Deleting alumno with id: " + alumno.getId());
alumnoRepository.deleteSkillByAlumnoId(alumno.getId()); // delete associated skills
alumnoRepository.deleteById(alumno.getId()); // then delete the alumno
}
}
}
}

@ -0,0 +1,96 @@
package com.example.proyectofinal.servicios;
import com.example.proyectofinal.models.empresas.Ciclo;
import com.example.proyectofinal.models.empresas.Familia;
import com.example.proyectofinal.repositories.empresas.CicloRepository;
import com.example.proyectofinal.servicios.implemetations.ICiclos;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class CicloService implements ICiclos {
@Autowired
private CicloRepository cicloRepository;
@Autowired
private AlumnoService alumnoService;
@Autowired
private OfertaService ofertaService;
@Override
public Page<Ciclo> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNum - 1,pageSize,sort);
return this.cicloRepository.findAll(pageable);
}
@Override
public List<Ciclo> findAll() {
return cicloRepository.findAll();
}
@Override
public Ciclo findById(Long id) {
return cicloRepository.findById(id).orElse(null);
}
@Override
public Ciclo findByName(String name) {
return null;
}
@Override
public Ciclo save(Ciclo ciclo) {
return cicloRepository.save(ciclo);
}
@Transactional
@Override
public void deleteById(Long id) {
Ciclo ciclo = cicloRepository.findById(id).orElse(null);
if(ciclo != null){
alumnoService.deleteByCiclo(ciclo.getId());
ofertaService.deleteByCicloId(ciclo.getId());
cicloRepository.deleteById(id);
}
}
@Override
public List<Ciclo> search(String query) {
return cicloRepository.search(query);
}
@Override
public void deleteByFamilia(Familia familia) {
}
@Override
public Ciclo exists(Ciclo ciclo) {
return null;
}
@Transactional
@Override
public void deleteByFamiliaId(Long id) {
List<Ciclo> ciclos = cicloRepository.findCicloByFamiliaId(id);
if(ciclos != null){
for (Ciclo ciclo : ciclos) {
System.out.println("Deleting ciclo with id: " + ciclo.getId());
alumnoService.deleteByCiclo(ciclo.getId());
ofertaService.deleteByCicloId(ciclo.getId());
cicloRepository.deleteById(ciclo.getId());
}
}
}
}

@ -27,12 +27,10 @@ public class ContactosService implements IContactos {
} }
@Override @Override
public Page<Contacto> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Contacto> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() : Sort.by(sortField).descending();
? Sort.by(sortField).ascending() : PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize, sort);
Sort.by(sortField).descending(); return this.contactoRepository.findAll(pageRequest);
Pageable pageable = PageRequest.of(pageNum - 1,pageSize,sort);
return this.contactoRepository.findAll(pageable);
} }
@Override @Override
@ -92,4 +90,6 @@ public class ContactosService implements IContactos {
public Contacto exists(Contacto contacto) { public Contacto exists(Contacto contacto) {
return contactoRepository.existsByNombreApe(contacto.getNombre(),contacto.getApellido(),contacto.getApellido2()); return contactoRepository.existsByNombreApe(contacto.getNombre(),contacto.getApellido(),contacto.getApellido2());
} }
} }

@ -5,24 +5,20 @@ import com.example.proyectofinal.models.empresas.Oferta;
import com.example.proyectofinal.models.empresas.Sucursal; import com.example.proyectofinal.models.empresas.Sucursal;
import com.example.proyectofinal.repositories.empresas.EmpressaRepository; import com.example.proyectofinal.repositories.empresas.EmpressaRepository;
import com.example.proyectofinal.repositories.empresas.OfertaRepository; import com.example.proyectofinal.repositories.empresas.OfertaRepository;
import com.example.proyectofinal.repositories.empresas.SkillRepository;
import com.example.proyectofinal.servicios.implemetations.IEmpresa; import com.example.proyectofinal.servicios.implemetations.IEmpresa;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@Service @Service
public class EmpresaService implements IEmpresa { public class EmpresaService implements IEmpresa {
@Autowired @Autowired
private EmpressaRepository empressaRepository; private EmpressaRepository empresaRepository;
@Autowired @Autowired
private ContactosService contactosService; private ContactosService contactosService;
@Autowired @Autowired
@ -35,32 +31,31 @@ public class EmpresaService implements IEmpresa {
@Override @Override
public List<Empresa> findAll() { public List<Empresa> findAll() {
return empressaRepository.findAll(); return empresaRepository.findAll();
} }
@Override @Override
public Page<Empresa> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Empresa> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() : Sort.by(sortField).descending();
? Sort.by(sortField).ascending() : PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize, sort);
Sort.by(sortField).descending(); Page<Empresa> result = empresaRepository.findAll(pageRequest);
Pageable pageable = PageRequest.of(pageNum - 1,pageSize,sort); return result;
return this.empressaRepository.findAll(pageable);
} }
@Override @Override
public Empresa findById(Long id) { public Empresa findById(Long id) {
return empressaRepository.findById(id).orElse(null); return empresaRepository.findById(id).orElse(null);
} }
@Override @Override
public Empresa save(Empresa empresa) { public Empresa save(Empresa empresa) {
return empressaRepository.save(empresa); return empresaRepository.save(empresa);
} }
@Transactional @Transactional
@Override @Override
public void deleteById(Long id) { public void deleteById(Long id) {
Empresa empresa = empressaRepository.findById(id).orElse(null); Empresa empresa = empresaRepository.findById(id).orElse(null);
if (empresa != null) { if (empresa != null) {
contactosService.deleteByEmpresa(empresa); contactosService.deleteByEmpresa(empresa);
List<Sucursal> sucursales = sucursalService.findByEmpresa(empresa); List<Sucursal> sucursales = sucursalService.findByEmpresa(empresa);
@ -72,25 +67,26 @@ public class EmpresaService implements IEmpresa {
} }
sucursalService.deleteById(sucursal.getId()); sucursalService.deleteById(sucursal.getId());
} }
empressaRepository.deleteById(id); empresaRepository.deleteById(id);
} }
} }
@Override @Override
public List<Empresa> search(String query ) { public List<Empresa> search(String query ) {
return empressaRepository.search(query); return empresaRepository.search(query);
} }
@Override @Override
public Empresa exists(Empresa empresa) { public Empresa exists(Empresa empresa) {
String cif = empresa.getCif(); String cif = empresa.getCif();
return empressaRepository.existsCif(cif); return empresaRepository.existsCif(cif);
} }
@Override @Override
public List<Empresa> findBySector(Long id) { public List<Empresa> findBySector(Long id) {
return empressaRepository.findBySector(id); return empresaRepository.findBySector(id);
} }
} }

@ -1,34 +1,65 @@
package com.example.proyectofinal.servicios; package com.example.proyectofinal.servicios;
import com.example.proyectofinal.models.empresas.Empresa;
import com.example.proyectofinal.models.empresas.Familia; import com.example.proyectofinal.models.empresas.Familia;
import com.example.proyectofinal.models.empresas.Oferta;
import com.example.proyectofinal.repositories.empresas.FamiliaRepository; import com.example.proyectofinal.repositories.empresas.FamiliaRepository;
import com.example.proyectofinal.servicios.implemetations.IFamilia;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service @Service
public class FamiliaService { public class FamiliaService implements IFamilia {
@Autowired @Autowired
private FamiliaRepository familiaRepository; private FamiliaRepository familiaRepository;
@Autowired
private CicloService cicloService;
@Override
public List<Familia> findAll() {
return familiaRepository.findAll();
}
public String createFamilia(String name) { @Override
if (familiaRepository.findByName(name).isPresent()) { public Page<Familia> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
return "Familia ya existe"; Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() : Sort.by(sortField).descending();
} else { PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize, sort);
Familia newFamilia = new Familia(); Page<Familia> result = familiaRepository.findAll(pageRequest);
newFamilia.setNombre(name); return result;
familiaRepository.save(newFamilia);
return "Familia creada";
} }
@Override
public Familia findById(Long id) {
return familiaRepository.findById(id).orElse(null);
}
@Override
public Familia findByName(String name) {
return null;
} }
public String updateFamilia(Long id, String name) { @Override
if (familiaRepository.findById(id).isPresent()) { public Familia save(Familia familia) {
Familia familia = familiaRepository.findById(id).get(); return familiaRepository.save(familia);
familia.setNombre(name);
familiaRepository.save(familia);
return "Familia actualizada";
} else {
return "Familia no encontrada";
} }
@Override
public void deleteById(Long id) {
System.out.println("Deleting familia with id: " + id);
cicloService.deleteByFamiliaId(id);
familiaRepository.deleteById(id);
}
@Override
public List<Familia> search(String query) {
return familiaRepository.search(query);
} }
} }

@ -1,17 +1,28 @@
package com.example.proyectofinal.servicios; package com.example.proyectofinal.servicios;
import com.example.proyectofinal.models.empresas.Oferta; import com.example.proyectofinal.models.empresas.Oferta;
import com.example.proyectofinal.models.empresas.Skill;
import com.example.proyectofinal.models.empresas.Sucursal; import com.example.proyectofinal.models.empresas.Sucursal;
import com.example.proyectofinal.repositories.empresas.OfertaRepository; import com.example.proyectofinal.repositories.empresas.OfertaRepository;
import com.example.proyectofinal.servicios.implemetations.IOferta; import com.example.proyectofinal.servicios.implemetations.IOferta;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
@Service @Service
public class OfertaService implements IOferta { public class OfertaService implements IOferta {
@Autowired
private EntityManager entityManager;
@Autowired @Autowired
private OfertaRepository ofertaRepository; private OfertaRepository ofertaRepository;
@ -21,8 +32,27 @@ public class OfertaService implements IOferta {
} }
@Override @Override
public Page<Oferta> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Oferta> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
return null; Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
Page<Oferta> page = this.ofertaRepository.findAll(pageable);
List<Oferta> ofertas = page.getContent();
for (Oferta oferta : ofertas) {
List<Object[]> skillsData = ofertaRepository.findSkillsByOfertaId(oferta.getId());
Set<Skill> skills = new HashSet<>();
for (Object[] skillData : skillsData) {
Skill skill = new Skill();
skill.setId((Long) skillData[0]);
skill.setNombre((String) skillData[1]);
skills.add(skill);
}
oferta.setSkills(skills);
}
return page;
} }
@Override @Override
@ -32,7 +62,7 @@ public class OfertaService implements IOferta {
@Override @Override
public Oferta findByName(String name) { public Oferta findByName(String name) {
return null; return ofertaRepository.findByNombre(name);
} }
@Override @Override
@ -40,18 +70,36 @@ public class OfertaService implements IOferta {
return ofertaRepository.save(oferta); return ofertaRepository.save(oferta);
} }
@Transactional
@Override @Override
public void deleteById(Long id) { public void deleteById(Long id) {
Oferta oferta = findById(id);
if (oferta != null) {
ofertaRepository.deleteSkillsByOfertaId(id);
ofertaRepository.deleteById(id); ofertaRepository.deleteById(id);
} }
}
@Override @Override
public List<Oferta> search(String query) { public List<Oferta> search(String query) {
return List.of(); return ofertaRepository.search(query);
} }
@Override @Override
public List<Oferta> findBySucursal(Sucursal sucursal) { public List<Oferta> findBySucursal(Sucursal sucursal) {
return ofertaRepository.findBySucursalId(sucursal.getId()); return ofertaRepository.findBySucursalId(sucursal.getId());
} }
@Transactional
@Override
public void deleteByCicloId(Long id) {
List<Oferta> ofertas = ofertaRepository.findByCiclold(id);
if (ofertas != null) {
for(Oferta oferta : ofertas){
System.out.println("Deleting oferta with id: " + oferta.getId());
ofertaRepository.deleteSkillsByOfertaId(oferta.getId());
ofertaRepository.deleteById(oferta.getId());
}
}
}
} }

@ -38,7 +38,7 @@ public class SectorService implements ISector {
} }
@Override @Override
public Page<Sector> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Sector> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() : ? Sort.by(sortField).ascending() :
Sort.by(sortField).descending(); Sort.by(sortField).descending();

@ -5,9 +5,15 @@ import com.example.proyectofinal.repositories.empresas.SkillRepository;
import com.example.proyectofinal.servicios.implemetations.ISkill; import com.example.proyectofinal.servicios.implemetations.ISkill;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
@Service @Service
public class SkillService implements ISkill { public class SkillService implements ISkill {
@ -20,8 +26,13 @@ public class SkillService implements ISkill {
} }
@Override @Override
public Page<Skill> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Skill> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
return null; Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNum - 1,pageSize,sort);
//System.out.println("TEST SKILL " +skillRepository.findAll(pageable));
return this.skillRepository.findAll(pageable);
} }
@Override @Override
@ -39,13 +50,23 @@ public class SkillService implements ISkill {
return skillRepository.save(skill); return skillRepository.save(skill);
} }
@Transactional
@Override @Override
public void deleteById(Long id) { public void deleteById(Long id) {
skillRepository.deleteSkillOferta(id);
skillRepository.deleteSkillAlumno(id);
skillRepository.deleteById(id); skillRepository.deleteById(id);
} }
@Override @Override
public List<Skill> search(String query) { public List<Skill> search(String query) {
return List.of(); return skillRepository.search(query);
}
@Override
public Set<Skill> findAllByIds(List<Long> skills) {
return new HashSet<>(skillRepository.findAllById(skills));
} }
} }

@ -29,11 +29,10 @@ public class SucursalService implements ISucursal {
@Override @Override
public List<Sucursal> findAll() { public List<Sucursal> findAll() {
return List.of(); return sucursalRepository.findAll();
} }
@Override @Override
public Page<Sucursal> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir) { public Page<Sucursal> findAllPaginated(int pageNum, int pageSize, String sortField, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending() : ? Sort.by(sortField).ascending() :
Sort.by(sortField).descending(); Sort.by(sortField).descending();
@ -61,7 +60,6 @@ public class SucursalService implements ISucursal {
Sucursal sucursal = findById(id); Sucursal sucursal = findById(id);
List<Oferta> ofertas = ofertaService.findBySucursal(sucursal); List<Oferta> ofertas = ofertaService.findBySucursal(sucursal);
for (Oferta oferta : ofertas) { for (Oferta oferta : ofertas) {
ofertaRepository.deleteSkillsByOfertaId(oferta.getId());
ofertaService.deleteById(oferta.getId()); ofertaService.deleteById(oferta.getId());
} }
sucursalRepository.deleteById(id); sucursalRepository.deleteById(id);
@ -82,4 +80,5 @@ public class SucursalService implements ISucursal {
return sucursalRepository.findByName(sucursal.getNombre()); return sucursalRepository.findByName(sucursal.getNombre());
} }
} }

@ -0,0 +1,23 @@
package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Alumno;
import java.util.List;
public interface IAlumno extends IPagination<Alumno> {
List<Alumno> findAll();
Alumno findById(Long id);
Alumno findByName(String name);
Alumno save(Alumno ciclo);
void deleteById(Long id);
List<Alumno> search(String query);
Alumno exists(Alumno alumno);
void deleteByCiclo(Long id);
}

@ -0,0 +1,27 @@
package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Ciclo;
import com.example.proyectofinal.models.empresas.Familia;
import java.util.List;
public interface ICiclos extends IPagination<Ciclo> {
List<Ciclo> findAll();
Ciclo findById(Long id);
Ciclo findByName(String name);
Ciclo save(Ciclo ciclo);
void deleteById(Long id);
List<Ciclo> search(String query);
void deleteByFamilia(Familia familia);
Ciclo exists(Ciclo ciclo);
void deleteByFamiliaId(Long id);
}

@ -2,16 +2,12 @@ package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Contacto; import com.example.proyectofinal.models.empresas.Contacto;
import com.example.proyectofinal.models.empresas.Empresa; import com.example.proyectofinal.models.empresas.Empresa;
import com.example.proyectofinal.models.empresas.Sucursal;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
public interface IContactos { public interface IContactos extends IPagination<Contacto> {
List<Contacto> findAll(); List<Contacto> findAll();
Page<Contacto> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Contacto findById(Long id); Contacto findById(Long id);
Contacto findByName(String name); Contacto findByName(String name);

@ -1,15 +1,13 @@
package com.example.proyectofinal.servicios.implemetations; package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Empresa; import com.example.proyectofinal.models.empresas.Empresa;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
public interface IEmpresa { public interface IEmpresa extends IPagination<Empresa> {
List<Empresa> findAll(); List<Empresa> findAll();
Page<Empresa> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Empresa findById(Long id); Empresa findById(Long id);

@ -0,0 +1,20 @@
package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Familia;
import java.util.List;
public interface IFamilia extends IPagination<Familia> {
List<Familia> findAll();
Familia findById(Long id);
Familia findByName(String name);
Familia save(Familia familia);
void deleteById(Long id);
List<Familia> search(String query);
}

@ -2,15 +2,12 @@ package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Oferta; import com.example.proyectofinal.models.empresas.Oferta;
import com.example.proyectofinal.models.empresas.Sucursal; import com.example.proyectofinal.models.empresas.Sucursal;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
public interface IOferta { public interface IOferta extends IPagination<Oferta> {
List<Oferta> findAll(); List<Oferta> findAll();
Page<Oferta> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Oferta findById(Long id); Oferta findById(Long id);
Oferta findByName(String name); Oferta findByName(String name);
@ -22,4 +19,6 @@ public interface IOferta {
List<Oferta> search(String query); List<Oferta> search(String query);
List<Oferta> findBySucursal(Sucursal sucursal); List<Oferta> findBySucursal(Sucursal sucursal);
void deleteByCicloId(Long id);
} }

@ -0,0 +1,8 @@
package com.example.proyectofinal.servicios.implemetations;
import org.springframework.data.domain.Page;
public interface IPagination<T> {
Page<T> findAllPaginated(int pageNum, int size, String sortField, String sortDir);
}

@ -1,14 +1,12 @@
package com.example.proyectofinal.servicios.implemetations; package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Sector; import com.example.proyectofinal.models.empresas.Sector;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
public interface ISector { public interface ISector extends IPagination<Sector> {
List<Sector> findAll(); List<Sector> findAll();
Page<Sector> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Sector findById(Long id); Sector findById(Long id);

@ -4,12 +4,11 @@ import com.example.proyectofinal.models.empresas.Skill;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
import java.util.Set;
public interface ISkill { public interface ISkill extends IPagination<Skill>{
List<Skill> findAll(); List<Skill> findAll();
Page<Skill> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Skill findById(Long id); Skill findById(Long id);
Skill findByName(String name); Skill findByName(String name);
@ -19,4 +18,6 @@ public interface ISkill {
void deleteById(Long id); void deleteById(Long id);
List<Skill> search(String query); List<Skill> search(String query);
Set<Skill> findAllByIds(List<Long> skills);
} }

@ -2,15 +2,12 @@ package com.example.proyectofinal.servicios.implemetations;
import com.example.proyectofinal.models.empresas.Empresa; import com.example.proyectofinal.models.empresas.Empresa;
import com.example.proyectofinal.models.empresas.Sucursal; import com.example.proyectofinal.models.empresas.Sucursal;
import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
public interface ISucursal { public interface ISucursal extends IPagination<Sucursal> {
List<Sucursal> findAll(); List<Sucursal> findAll();
Page<Sucursal> finadAllpaginated(int pageNum, int pageSize, String sortField, String sortDir);
Sucursal findById(Long id); Sucursal findById(Long id);
Sucursal findByName(String name); Sucursal findByName(String name);

@ -1,6 +1,6 @@
$('#entriesCount').on('change', function(){ $('#entriesCount').on('change', function(){
var entriesCount = $('#entriesCount').val(); var entriesCount = $('#entriesCount').val();
console.log(entriesCount); console.log('entriesCount:', entriesCount);
var url = window.location.href; var url = window.location.href;
var newUrl; var newUrl;
if (url.includes('size=')) { if (url.includes('size=')) {
@ -8,6 +8,7 @@ $('#entriesCount').on('change', function(){
} else { } else {
newUrl = url.includes('?') ? url + '&size=' + entriesCount : url + '?size=' + entriesCount; newUrl = url.includes('?') ? url + '&size=' + entriesCount : url + '?size=' + entriesCount;
} }
console.log('newUrl:', newUrl);
window.location.href = newUrl; window.location.href = newUrl;
}); });

@ -135,16 +135,16 @@ html, body {
padding:10px; padding:10px;
} }
#edit-icon, #delete-icon { .edit-icon, #delete-icon {
min-width: 24px; min-width: 24px;
} }
#edit-icon { .edit-icon {
color: #ffa600; color: #ffa600;
margin-right: 10px; margin-right: 10px;
margin-left: 10px; margin-left: 10px;
font-size: 24px; font-size: 24px;
} }
#delete-icon { .delete-icon {
color: red; color: red;
margin-left: 5px; margin-left: 5px;
font-size: 24px; font-size: 24px;
@ -215,5 +215,8 @@ html, body {
.modal p{ .modal p{
font-size: 20px; font-size: 20px;
} }
.scrollable-table {
overflow-x: auto;
}

@ -0,0 +1,205 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Creacion: Alumno</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Añadir Alumno<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/contacto/save}" method="post" enctype="multipart/form-data" th:object="${alumno}">
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="75" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="cif">Apellido</label>
<div class = "col-sm-9">
<input type="text" th:field="*{apellido}" required minlength="2" maxlength="75" title="Entra un nombre" class="form-control" id="cif">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="apellido2">Apellido2</label>
<div class = "col-sm-9">
<input type="text" th:field="*{apellido2}" minlength="2" maxlength="75" class="form-control" id="apellido2">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="fechaNacimiento">Fecha de Nacimiento</label>
<div class = "col-sm-9">
<input type="date" th:field="*{fechaNacimiento}" required class="form-control" id="fechaNacimiento" title="Introduce fecha">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="genero">Genero</label>
<div class="col-sm-9">
<select th:field="*{genero}" class="form-control" id="genero" required>
<option value="">Selecciona un genero</option>
<option value="Mujer">Mujer</option>
<option value="Varon">Varon</option>
</select>
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nia">Nia</label>
<div class = "col-sm-9">
<!--TODO: Añadir validacion de nia-->
<input type="text" th:field="*{nia}" title="Entra un nia correcto" class="form-control" id="nia">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="dni">DNI/NIE</label>
<div class="col-sm-9">
<input type="text" th:field="*{dni}" required class="form-control" id="dni" title="Introduce DNI/NIE">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="correo">Correo</label>
<div class="col-sm-9">
<input type="email" th:field="*{correo}" required class="form-control" id="correo" title="Introduce correo">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="correo2">Correo2</label>
<div class="col-sm-9">
<input type="email" th:field="*{correo2}" class="form-control" id="correo2" title="Introduce correo alternativo">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="nacionalidad">Nacionalidad</label>
<div class="col-sm-9">
<input type="text" th:field="*{nacionalidad}" class="form-control" id="nacionalidad" title="Introduce nacionalidad">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="keywords">Keywords</label>
<div class="col-sm-9">
<input type="text" th:field="*{keywords}" class="form-control" id="keywords" title="Introduce keywords">
</div>
</div>
<!-- Ciclos -->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="ciclo">Ciclo</label>
<div class="col-sm-9">
<select th:field="*{ciclo.id}" class="form-control" id="ciclo">
<option th:each="ciclo : ${ciclos}" th:value="${ciclo.id}" th:text="${ciclo.nombre}"></option>
</select>
</div>
</div>
<div class="skills-container">
<h2>Select Skills</h2>
<select id="skills" multiple>
<option th:each="skill : ${skills}" th:value="${skill.id}" th:text="${skill.nombre}"></option>
</select>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('#skills').select2();
});
function goBack() {
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'ciclo', value: $('#ciclo').val()});
formDataArray.push({name: 'skills', value: $('#skills').val()});
$.ajax({
url: '/alumno/save',
type: 'post',
data: $.param(formDataArray),
success: function (message) {
if(message === "El alumno fue guardado con exito") {
alert("El alumno fue guardado con exito")
window.history.go(-1);
} else if(message === "El alumno ya existe"){
alert("El alumno ya existe");
window.history.go(-1);
}else{
alert("Error, consulte a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,203 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update: Alumno</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Editar datos de Alumno<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/alumno/update}" method="post" enctype="multipart/form-data" th:object="${alumno}">
<input type="hidden" th:field="*{id}"/>
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="75" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="cif">Apellido</label>
<div class = "col-sm-9">
<input type="text" th:field="*{apellido}" required minlength="2" maxlength="75" title="Entra un nombre" class="form-control" id="cif">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="apellido2">Apellido2</label>
<div class = "col-sm-9">
<input type="text" th:field="*{apellido2}" minlength="2" maxlength="75" class="form-control" id="apellido2">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="fechaNacimiento">Fecha de Nacimiento</label>
<div class = "col-sm-9">
<input type="date" th:field="*{fechaNacimiento}" required class="form-control" id="fechaNacimiento" title="Introduce fecha">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="genero">Genero</label>
<div class="col-sm-9">
<select th:field="*{genero}" class="form-control" id="genero" required>
<option value="">Selecciona un genero</option>
<option value="Mujer">Mujer</option>
<option value="Varon">Varon</option>
</select>
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nia">Nia</label>
<div class = "col-sm-9">
<!--TODO: Añadir validacion de nia-->
<input type="text" th:field="*{nia}" title="Entra un nia correcto" class="form-control" id="nia">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="dni">DNI/NIE</label>
<div class="col-sm-9">
<input type="text" th:field="*{dni}" required class="form-control" id="dni" title="Introduce DNI/NIE">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="correo">Correo</label>
<div class="col-sm-9">
<input type="email" th:field="*{correo}" required class="form-control" id="correo" title="Introduce correo">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="correo2">Correo2</label>
<div class="col-sm-9">
<input type="email" th:field="*{correo2}" class="form-control" id="correo2" title="Introduce correo alternativo">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="nacionalidad">Nacionalidad</label>
<div class="col-sm-9">
<input type="text" th:field="*{nacionalidad}" class="form-control" id="nacionalidad" title="Introduce nacionalidad">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="keywords">Keywords</label>
<div class="col-sm-9">
<input type="text" th:field="*{keywords}" class="form-control" id="keywords" title="Introduce keywords">
</div>
</div>
<!-- Ciclos -->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="ciclo">Ciclo</label>
<div class="col-sm-9">
<select th:field="*{ciclo.id}" class="form-control" id="ciclo">
<option th:each="ciclo : ${ciclos}" th:value="${ciclo.id}" th:text="${ciclo.nombre}"></option>
</select>
</div>
</div>
<div class="skills-container">
<h2>Select Skills</h2>
<select id="skills" multiple>
<option th:each="skill : ${skills}" th:value="${skill.id}" th:text="${skill.nombre}" th:selected="${alumno.skills.contains(skill)}"></option>
</select>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('#skills').select2();
});
function goBack() {
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'ciclo', value: $('#ciclo').val()});
formDataArray.push({name: 'skills', value: $('#skills').val()});
$.ajax({
url: '/alumno/update',
type: 'post',
data: $.param(formDataArray),
success: function (message) {
if(message === "El alumno fue actualizado con exito") {
alert("El alumno fue actualizado con exito")
window.history.go(-1);
} else {
alert("Error, consulte a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Creacion: Ciclo</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Añadir Ciclo<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/ciclo/save}" method="post" enctype="multipart/form-data" th:object="${ciclo}">
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="125" title="Entra un Nombre" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="codigo">Codigo</label>
<div class = "col-sm-9">
<input type="text" th:field="*{codigo}" required minlength="2" maxlength="15" title="Entra un codigo" class="form-control" id="codigo">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="familia">Familia</label>
<div class = "col-sm-9">
<select th:field="*{familia.id}" class="form-control" id="familia">
<option th:each="familia : ${familias}" th:value="${familia.id}" th:text="${familia.nombre}"></option>
</select>
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
function goBack() {
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'familia', value: $('#familia').val()});
$.ajax({
url: '/ciclo/save',
type: 'post',
data: $.param(formDataArray),
success: function (message) {
if(message === "El ciclo fue guardado con exito") {
alert("El ciclo fue guardado con exito")
window.history.go(-1); // Go back two pages
} else if(message === "Este ciclo ya existe en la base de datos"){
alert("Este ciclo ya existe en la base de datos");
window.history.go(-1);
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update: Ciclo</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Editar datos de Ciclo<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/ciclo/update}" method="post" enctype="multipart/form-data" th:object="${ciclo}">
<input type="hidden" th:field="*{id}"/>
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="125" title="Entra un Nombre" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="codigo">Codigo</label>
<div class = "col-sm-9">
<input type="text" th:field="*{codigo}" required minlength="2" maxlength="15" title="Entra un codigo" class="form-control" id="codigo">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="familia">Familia</label>
<div class = "col-sm-9">
<select th:field="*{familia.id}" class="form-control" id="familia">
<option th:each="familia : ${familias}" th:value="${familia.id}" th:text="${familia.nombre}"></option>
</select>
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
function goBack() {
console.log("goBack function called");
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'familia', value: $('#familia').val()});
$.ajax({
url: '/ciclo/update',
type: 'post',
data: $.param(formDataArray),
success: function (message) {
if(message === "Los datos del ciclo fue renovados con exito") {
alert("Los datos del ciclo fue renovados con exito")
window.history.go(-1); // Go back two pages
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -4,8 +4,10 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Creacion: Familia</title> <title>Creacion: Familia</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}"> <link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<link rel="stylesheet" type="text/css" th:href="@{/back_button.css}">
<style> <style>
form { form {
display: flex; display: flex;
@ -19,14 +21,18 @@
margin-top: 100px; margin-top: 100px;
} }
form input[type="text"], form input[type="submit"] { .btn {
font-size: 20px; margin-top: 25px;
padding: 10px; margin-right: 5px;
margin-bottom: 10px; width: 120px;
font-family: Verdana, Geneva, Tahoma, sans-serif; height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
} }
form input[type="text"]{ form input[type="text"]{
width: 40%; width: 75%;
} }
form label{ form label{
font-size: 20px; font-size: 20px;
@ -43,35 +49,58 @@
</style> </style>
</head> </head>
<body> <body>
<h1>CREAR FAMILIA<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1> <h1>Añadir Familia<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<!--<form action="/familia/crearFamilia" method="post">-->
<!--TODO: Ask why this doesnt work and if it has to do with the jumping from editcontroler to familia controler--> <form th:action="@{/familia/save}" method="post" enctype="multipart/form-data" th:object="${familia}">
<form th:action="@{/templates/admin/familia/crearFamilia}" method="post"> <div class="p-3">
<label for="name">Nombre de Familia de Ciclos:</label><br> <div class ="form-group row">
<input type="text" id="name" name="name"><br> <label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<input type="submit" value="Crear"> <div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="75" class="form-control" id="nombre">
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form> </form>
<button onclick="location.href='/editMain'" class="back-button">Atras</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script> <script>
function goBack() {
window.history.back();
}
$(document).ready(function () { $(document).ready(function () {
$("form").on("submit", function (event) { $("form").on("submit", function (event) {
event.preventDefault(); event.preventDefault();
var formData = $(this).serialize();
formData += '&familia=';
$.ajax({ $.ajax({
url: '/familia/crearFamilia', url: '/familia/save',
type: 'post', type: 'post',
data: $(this).serialize(), data: formData,
success: function(response){ success: function (message) {
if (response.startsWith('redirect:')) { if(message === "La familia fue guardado con exito") {
alert("Familia creada con exito"); alert("La familia fue guardado con exito")
window.location.href = response.substring(9); window.history.go(-1); // Go back two pages
} else if(message === "Este familia ya existe en la base de datos"){
alert("Este familia ya existe en la base de datos");
window.history.go(-1);
}else{ }else{
alert(response); alert("Error, consulata a los informaticos")
window.history.go(-1)
} }
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
} }
}); });
}); });
}); });
</script> </script>
</body> </body>
</html> </html>

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update: Familia</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Editar datos de Familia<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/familia/update}" method="post" enctype="multipart/form-data" th:object="${familia}">
<input type="hidden" th:field="*{id}"/>
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="75" class="form-control" id="nombre">
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
function goBack() {
console.log("goBack function called");
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formData = $(this).serialize();
formData += '&familia=';
$.ajax({
url: '/familia/update',
type: 'post',
data: formData,
success: function (message) {
if(message === "La familia ha sido actualizado con exito") {
alert("Los datos del familia fue renovada con exito")
window.history.go(-1); // Go back two pages
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,156 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Creacion: Oferta</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Añadir Oferta<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/oferta/save}" method="post" enctype="multipart/form-data" th:object="${oferta}">
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="128" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="fecha">Fecha</label>
<div class = "col-sm-9">
<input type="date" th:field="*{fecha}" required class="form-control" id="fecha" title="Introduce fecha">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="descripcion">Descripcion</label>
<div class = "col-sm-9">
<input type="text" th:field="*{descripcion}" class="form-control" id="descripcion">
</div>
</div>
<!-- Ciclos -->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="ciclo">Ciclo</label>
<div class="col-sm-9">
<select th:field="*{ciclo.id}" class="form-control" id="ciclo">
<option th:each="ciclo : ${ciclos}" th:value="${ciclo.id}" th:text="${ciclo.nombre}"></option>
</select>
</div>
</div>
<!-- Sucursals-->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="sucursal">Sucursal</label>
<div class="col-sm-9">
<select th:field="*{sucursal.id}" class="form-control" id="sucursal">
<option th:each="sucursal : ${sucursals}" th:value="${sucursal.id}" th:text="${sucursal.nombre}"></option>
</select>
</div>
</div>
<div class="skills-container">
<h2>Select Skills</h2>
<select id="skills" multiple>
<option th:each="skill : ${skills}" th:value="${skill.id}" th:text="${skill.nombre}"></option>
</select>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('#skills').select2();
});
function goBack() {
//console.log("goBack function called");
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'ciclo', value: $('#ciclo').val()});
formDataArray.push({name: 'sucursal', value: $('#sucursal').val()});
formDataArray.push({name: 'skills', value: $('#skills').val()});
$.ajax({
url: '/oferta/save',
type: 'post',
data: $.param(formDataArray), // use $.param(formDataArray) instead of formData
success: function (message) {
if(message === "La oferta fue guadada con exito") {
alert("La oferta fue guadada con exito")
window.history.go(-1); // Go back two pages
} else if(message === "Esta oferta ya existe en la base de datos"){
alert("Esta oferta ya existe en la base de datos");
window.history.go(-1);
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update: Oferta</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Editar datos de Oferta<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/oferta/update}" method="post" enctype="multipart/form-data" th:object="${oferta}">
<input type="hidden" th:field="*{id}"/>
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="128" class="form-control" id="nombre">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="fecha">Fecha</label>
<div class = "col-sm-9">
<input type="date" th:field="*{fecha}" required class="form-control" id="fecha" title="Introduce fecha en formato aaaa-mm-dd como 2022-05-05">
</div>
</div>
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="descripcion">Descripcion</label>
<div class = "col-sm-9">
<input type="text" th:field="*{descripcion}" class="form-control" id="descripcion">
</div>
</div>
<!-- Ciclos -->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="ciclo">Ciclo</label>
<div class="col-sm-9">
<select th:field="*{ciclo.id}" class="form-control" id="ciclo">
<option th:each="ciclo : ${ciclos}" th:value="${ciclo.id}" th:text="${ciclo.nombre}"></option>
</select>
</div>
</div>
<!-- Sucursals-->
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="sucursal">Sucursal</label>
<div class="col-sm-9">
<select th:field="*{sucursal.id}" class="form-control" id="sucursal">
<option th:each="sucursal : ${sucursals}" th:value="${sucursal.id}" th:text="${sucursal.nombre}"></option>
</select>
</div>
</div>
<div class="skills-container">
<h2>Select Skills</h2>
<select id="skills" multiple>
<option th:each="skill : ${skills}" th:value="${skill.id}" th:text="${skill.nombre}" th:selected="${oferta.skills.contains(skill)}"></option>
</select>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('#skills').select2();
});
function goBack() {
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formDataArray = $(this).serializeArray();
formDataArray.push({name: 'ciclo', value: $('#ciclo').val()});
formDataArray.push({name: 'sucursal', value: $('#sucursal').val()});
formDataArray.push({name: 'skills', value: $('#skills').val()});
$.ajax({
url: '/oferta/update',
type: 'post',
data: $.param(formDataArray),
success: function (message) {
if(message === "La oferta fue guadada con exito") {
alert("La oferta fue renovada con exito")
window.history.go(-1);
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Creacion: Skill</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Añadir Skill<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/skill/save}" method="post" enctype="multipart/form-data" th:object="${skill}">
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="128" class="form-control" id="nombre">
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
function goBack() {
console.log("goBack function called");
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formData = $(this).serialize();
formData += '&skill=';
$.ajax({
url: '/skill/save',
type: 'post',
data: formData,
success: function (message) {
if(message === "El skill fue guardado con exito") {
alert("El skill fue guardado con exito")
window.history.go(-1); // Go back two pages
} else if(message === "Este skill ya existe en la base de datos"){
alert("Este skill ya existe en la base de datos");
window.history.go(-1);
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update: Skill</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/top.css}">
<style>
form {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: none;
margin: auto;
padding: 25px;
margin-top: 100px;
}
.btn {
margin-top: 25px;
margin-right: 5px;
width: 120px;
height: 40px;
font-family: Verdana;
}
form input[type="submit"], form input[type="button"] {
width: 100px;
}
form input[type="text"]{
width: 75%;
}
form label{
font-size: 20px;
margin-bottom: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
body, h1 {
margin: 0;
padding: 0;
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>Editar Skill<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<form th:action="@{/skill/update}" method="post" enctype="multipart/form-data" th:object="${skill}">
<input type="hidden" th:field="*{id}"/>
<div class="p-3">
<div class ="form-group row">
<label class="col-sm-3 col-form-label" for="nombre">Nombre</label>
<div class = "col-sm-9">
<input type="text" th:field="*{nombre}" required minlength="2" maxlength="128" class="form-control" id="nombre">
</div>
</div>
<div class="text-center">
<input type="submit" value="Guardar" class="btn"/>
<input type="button" value="Cancelar" id="btnCancelar" class="btn" onclick="goBack()"/>
</div>
</div>
</form>
<script>
function goBack() {
console.log("goBack function called");
window.history.back();
}
$(document).ready(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var formData = $(this).serialize();
formData += '&skill=';
$.ajax({
url: '/skill/update',
type: 'post',
data: formData,
success: function (message) {
if(message === "El skill fue renovado") {
alert("El skill fue renovado")
window.history.go(-1);
}else{
alert("Error, consulata a los informaticos")
window.history.go(-1)
}
},
error: function (jqXHR) {
alert(jqXHR.responseText);
window.history.back();
}
});
});
});
</script>
</body>
</html>

@ -3,40 +3,101 @@
<head> <head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}"> <link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Title</title> <title>Lista: Alumnos</title>
<style> <style>
</style> </style>
</head> </head>
<body> <body>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <div class="header">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script> <button onclick="goBack()">Atras</button>
<h1>Listado de Alumnos<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1> <h1>Listado de Alumnos</h1>
<div class="table"> <a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a>
<table class ="table table-hover table-responsive-xl"> </div>
<input type="text" id="myInput" placeholder="Buscar por...."> <i class="fas fa-plus" id="create-icon"></i>
<div class="scrollable-table">
<table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th>Id</th> <th class="table-header">
<th>Nombre</th> <a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
<th>Apellido 1</th> Nombre
<th>Apellido 2</th> </a>
<th>Fecha Nacimiento</th> </th>
<th>Genero</th> <th class="table-header">
<th>NIA</th> <a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=apellido&sortDir=' + ${reverseSortDir}}">
<th>DNI/NIE</th> Apellido
<th>Correo 1</th> </a>
<th>Correo 2</th> </th>
<th>Nacionalidad</th> <th class="table-header">
<th>Keywords</th> <a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=apellido2&sortDir=' + ${reverseSortDir}}">
<th>Ciclo</th> Apellido2
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=fechaNacimiento&sortDir=' + ${reverseSortDir}}">
Fecha Nacimeinto
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=genero&sortDir=' + ${reverseSortDir}}">
Genero
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=nia&sortDir=' + ${reverseSortDir}}">
NIA
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=dni&sortDir=' + ${reverseSortDir}}">
DNI/NIE/Numero de pasaporte
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=correo&sortDir=' + ${reverseSortDir}}">
Correo
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=correo2&sortDir=' + ${reverseSortDir}}">
Correo2
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=nacionalidad&sortDir=' + ${reverseSortDir}}">
Nacionalidad
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=keywords&sortDir=' + ${reverseSortDir}}">
Keywords
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/alumnos/page/' + ${currentPage} + '?sortField=ciclo.nombre&sortDir=' + ${reverseSortDir}}">
Ciclo
</a>
</th>
<th class="table-header">
Skills
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="alumno :${alumnos}"> <tr class="cell" th:each="alumno :${items}" th:data-id="${alumno.id}">
<td>[[${alumno.id}]]</td> <td>
<td>[[${alumno.nombre}]]</td> [[${alumno.nombre}]]
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>[[${alumno.apellido}]]</td> <td>[[${alumno.apellido}]]</td>
<td>[[${alumno.apellido2}]]</td> <td>[[${alumno.apellido2}]]</td>
<td>[[${alumno.fechaNacimiento}]]</td> <td>[[${alumno.fechaNacimiento}]]</td>
@ -46,19 +107,218 @@
<td>[[${alumno.correo}]]</td> <td>[[${alumno.correo}]]</td>
<td>[[${alumno.correo2}]]</td> <td>[[${alumno.correo2}]]</td>
<td>[[${alumno.nacionalidad}]]</td> <td>[[${alumno.nacionalidad}]]</td>
<td class="keywords-cell" th:each="keyword : ${#strings.arraySplit(alumno.keywords, ',')}">[[${keyword}]]</td> <td>[[${alumno.keywords}]]</td>
<td>[[${alumno.ciclo.nombre}]]</td> <td>[[${alumno.ciclo.nombre}]]</td>
<td>
<span th:each="skill : ${alumno.skills}" th:text="${skill.nombre} + ' '"></span>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<button onclick="goBack()">Atras</button> <div class="page">
<nav aria-label="Page navigation" id="paginationControls">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/alumnos/page/' + ${1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Prim</a>
</li>
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/alumnos/page/' + ${currentPage - 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ant</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(1, totalPages)}" th:classappend="${pageNum eq currentPage ? 'active' : ''}">
<th:block th:if="${pageNum lt 3 or pageNum gt totalPages - 2 or pageNum eq currentPage - 2 or pageNum eq currentPage - 1 or pageNum eq currentPage or pageNum eq currentPage + 1 or pageNum eq currentPage + 2}">
<a class="page-link" th:href="@{'/buscador/alumnos/page/' + ${pageNum} + '?query=' + ${query} + '&size=' + ${currentSize}}">[[${pageNum}]]</a>
</th:block>
<th:block th:if="${pageNum eq 3 and currentPage gt 5}">...</th:block>
<th:block th:if="${pageNum eq totalPages - 2 and currentPage lt totalPages - 4}">...</th:block>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/alumnos/page/' + ${currentPage + 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Sig</a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/alumnos/page/' + ${totalPages} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ult</a>
</li>
</ul>
</nav>
</div>
<select id="entriesCount">
<option th:each="item : ${itemsPage}" th:value="${item}" th:text="${item}" th:selected="${item == currentSize}"></option>
</select>
<div id="modalDelete" class ="modal">
<div class="modal-content">
<p>¿Estas seguro que quires borar este elemnto?</p>
<span class="delete">Borar</span>
<span class="close">Cancelar</span>
</div>
</div>
<script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
</script> var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/alumno/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/alumno/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "El alumno ha sido eliminado") {
alert("Alumno borrado con exito");
window.location.reload();
} else {
alert("Error al borrar alumno");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = '';
entriesCountDropdown.style.display = '';
table.style.pointerEvents = '';
location.reload();
} else {
isSearchBarUsed = true;
paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none';
fetch('/buscador/alumnos/search?query=' + query)
.then(response => response.json())
.then(data => {
var tableBody = document.querySelector('#table tbody');
tableBody.innerHTML = '';
data.forEach(alumno => {
var row = document.createElement('tr');
row.dataset.id = alumno.id;
row.innerHTML = `
<td>
${alumno.nombre}
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>${alumno.apellido}</td>
<td>${alumno.apellido2}</td>
<td>${alumno.fechaNacimiento}</td>
<td>${alumno.genero}</td>
<td>${alumno.nia}</td>
<td>${alumno.dni}</td>
<td>${alumno.correo}</td>
<td>${alumno.correo2}</td>
<td>${alumno.nacionalidad}</td>
<td>${alumno.keywords}</td>
<td>${alumno.ciclo.nombre}</td>
<td>
${alumno.skills.map(skill => skill.nombre).join(', ')}
</td>
`;
tableBody.appendChild(row);
});
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
});
table.style.pointerEvents = 'auto';
});
}
});
document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
// Create a new observer
const observer = new MutationObserver(function() {
// Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/alumno/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script>
</body> </body>
</html> </html>

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<h1>Listado de Ciclos<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1>
<div class="table">
<table class ="table table-hover table-responsive-xl">
<thead class="thread-light">
<tr>
<th>Id</th>
<th>Nombre</th>
<th>Familia</th>
</tr>
</thead>
<tbody>
<tr class="cell" th:each="ciclo :${ciclos}">
<td>[[${ciclo.id}]]</td>
<td>[[${ciclo.nombre}]]</td>
<td>[[${ciclo.familia.nombre}]]</td>
</tr>
</tbody>
</table>
</div>
<button onclick="goBack()">Atras</button>
<script>
function goBack() {
window.history.back();
}
</script>
</body>
</html>

@ -0,0 +1,251 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8">
<title>Lista: Cilos</title>
<style>
</style>
</head>
<body>
<div class="header">
<button onclick="goBack()">Atras</button>
<h1>Listado de Ciclos</h1>
<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a>
</div>
<input type="text" id="myInput" placeholder="Buscar por...."> <i class="fas fa-plus" id="create-icon"></i>
<div class="table-container">
<table class="table" id="table">
<thead class="thread-light">
<tr>
<th class="table-header">
<a th:href="@{'/buscador/ciclos/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
Nombre
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ciclos/page/' + ${currentPage} + '?sortField=codigo&sortDir=' + ${reverseSortDir}}">
Codigo
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ciclos/page/' + ${currentPage} + '?sortField=familia.nombre&sortDir=' + ${reverseSortDir}}">
Familia
</a>
</th>
</thead>
<tbody>
<tr class="cell" th:each="ciclo :${items}" th:data-id="${ciclo.id}">
<td>
[[${ciclo.nombre}]]
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>[[${ciclo.codigo}]]</td>
<td>[[${ciclo.familia.nombre}]]</td>
</tr>
</tbody>
</table>
</div>
<div class="page">
<nav aria-label="Page navigation" id="paginationControls">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ciclos/page/' + ${1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Prim</a>
</li>
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ciclos/page/' + ${currentPage - 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ant</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(1, totalPages)}" th:classappend="${pageNum eq currentPage ? 'active' : ''}">
<th:block th:if="${pageNum lt 3 or pageNum gt totalPages - 2 or pageNum eq currentPage - 2 or pageNum eq currentPage - 1 or pageNum eq currentPage or pageNum eq currentPage + 1 or pageNum eq currentPage + 2}">
<a class="page-link" th:href="@{'/buscador/ciclos/page/' + ${pageNum} + '?query=' + ${query} + '&size=' + ${currentSize}}">[[${pageNum}]]</a>
</th:block>
<th:block th:if="${pageNum eq 3 and currentPage gt 5}">...</th:block>
<th:block th:if="${pageNum eq totalPages - 2 and currentPage lt totalPages - 4}">...</th:block>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ciclos/page/' + ${currentPage + 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Sig</a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ciclos/page/' + ${totalPages} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ult</a>
</li>
</ul>
</nav>
</div>
<select id="entriesCount">
<option th:each="item : ${itemsPage}" th:value="${item}" th:text="${item}" th:selected="${item == currentSize}"></option>
</select>
<div id="modalDelete" class ="modal">
<div class="modal-content">
<p>¿Estas seguro que quires borar este elemnto?</p>
<span class="delete">Borar</span>
<span class="close">Cancelar</span>
</div>
</div>
<script src="/orderTable.js"></script>
<script>
function goBack() {
window.history.back();
}
var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/ciclo/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/ciclo/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "El ciclo ha sido eliminado") {
alert("Cilco borrado con exito");
window.location.reload();
} else {
alert("Error al borrar el ciclo");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = '';
entriesCountDropdown.style.display = '';
table.style.pointerEvents = '';
location.reload();
} else {
isSearchBarUsed = true;
paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none';
fetch('/buscador/ciclos/search?query=' + query)
.then(response => response.json())
.then(data => {
var tableBody = document.querySelector('#table tbody');
tableBody.innerHTML = '';
data.forEach(ciclo => {
var row = document.createElement('tr');
row.dataset.id = ciclo.id;
row.innerHTML = `
<td>
${ciclo.nombre}
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>${ciclo.codigo}</td>
<td>${ciclo.familia.nombre}</td>
`;
tableBody.appendChild(row);
});
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
});
table.style.pointerEvents = 'auto';
});
}
});
document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
// Create a new observer
const observer = new MutationObserver(function() {
// Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/ciclo/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script>
</body>
</html>

@ -25,11 +25,6 @@
<table class="table" id="table"> <table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th class="table-header">
<a th:href="@{'/buscador/contactos/page/' + ${currentPage} + '?sortField=id&sortDir=' + ${reverseSortDir}}">
Id
</a>
</th>
<th class="table-header"> <th class="table-header">
<a th:href="@{'/buscador/contactos/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}"> <a th:href="@{'/buscador/contactos/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
Nombre Nombre
@ -63,12 +58,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="contacto :${contactos}"> <tr class="cell" th:each="contacto :${items}" th:data-id="${contacto.id}">
<td>[[${contacto.id}]]</td>
<td> <td>
[[${contacto.nombre}]] [[${contacto.nombre}]]
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>[[${contacto.apellido}]]</td> <td>[[${contacto.apellido}]]</td>
<td>[[${contacto.apellido2}]]</td> <td>[[${contacto.apellido2}]]</td>
@ -120,22 +114,79 @@
<script src="/orderTable.js"></script> <script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
document.querySelector('#myInput').addEventListener('input', function() { var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/contacto/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/contacto/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "El contacto ha sido eliminado") {
alert("Contacto borrado con exito");
window.location.reload();
} else {
alert("Error al borrar contacto");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value; var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls'); var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount'); var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') { if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = ''; paginationControls.style.display = '';
entriesCountDropdown.style.display = ''; entriesCountDropdown.style.display = '';
table.style.pointerEvents = ''; table.style.pointerEvents = '';
location.reload(); location.reload();
} else { } else {
isSearchBarUsed = true;
paginationControls.style.display = 'none'; paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none'; entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none'; table.style.pointerEvents = 'none';
@ -147,12 +198,12 @@
tableBody.innerHTML = ''; tableBody.innerHTML = '';
data.forEach(contacto => { data.forEach(contacto => {
var row = document.createElement('tr'); var row = document.createElement('tr');
row.dataset.id = contacto.id;
row.innerHTML = ` row.innerHTML = `
<td>${contacto.id}</td>
<td> <td>
${contacto.nombre} ${contacto.nombre}
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>${contacto.apellido}</td> <td>${contacto.apellido}</td>
<td>${contacto.apellido2}</td> <td>${contacto.apellido2}</td>
@ -162,56 +213,59 @@
`; `;
tableBody.appendChild(row); tableBody.appendChild(row);
}); });
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
}); });
} document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
}); });
document.getElementById('create-icon').addEventListener('click', function() { table.style.pointerEvents = 'auto';
window.location = "/admin/contacto/create"; });
}
}); });
document.querySelector('#table').addEventListener('click', function(event) { document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('#edit-icon')) { if (event.target.matches('.edit-icon')) {
const rowId = event.target.closest('tr').firstElementChild.textContent; handleEdit(event);
window.location = "/admin/contacto/update/" + rowId; } else if (event.target.matches('.delete-icon')) {
} else if (event.target.matches('#delete-icon')) { handleDelete(event);
const rowId = event.target.closest('tr').firstElementChild.textContent; }
var modal = document.getElementById("modalDelete"); });
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block"; // Create a new observer
document.body.style.pointerEvents = 'none'; const observer = new MutationObserver(function() {
modal.style.pointerEvents = 'auto'; // Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
closeSpan.onclick = function() { // Start observing the document with the configured parameters
modal.style.display = "none"; observer.observe(document.querySelector('#table tbody'), { childList: true });
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() { document.getElementById('create-icon').addEventListener('click', function() {
$.ajax({ console.log("Create button clicked : TEST");
url: '/contacto/delete/' + rowId, window.location = "/admin/contacto/create";
type: 'GET',
success: function(response) {
if (response==="El contacto ha sido eliminado") {
alert("Contacto borrada con exito");
window.location.reload();
}else{
alert("Error al borrar el contacto");
}
}
}); });
}
window.onclick = function(event) { var tableHeaders = document.querySelectorAll('.table-header');
if (event.target === modal) { tableHeaders.forEach(function(header) {
modal.style.display = "none"; header.addEventListener('click', function(event) {
document.body.style.pointerEvents = 'auto'; // If the search bar is currently being used, prevent the default action of the click event
} if (isSearchBarUsed) {
} event.preventDefault();
} }
}); });
});
</script> </script>
</body> </body>
</html> </html>

@ -25,11 +25,6 @@
<table class="table" id="table"> <table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th class="table-header">
<a th:href="@{'/buscador/empresas/page/' + ${currentPage} + '?sortField=id&sortDir=' + ${reverseSortDir}}">
Id
</a>
</th>
<th class="table-header"> <th class="table-header">
<a th:href="@{'/buscador/empresas/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}"> <a th:href="@{'/buscador/empresas/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
Nombre Nombre
@ -63,12 +58,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="empresa :${empresas}"> <tr class="cell" th:each="empresa :${items}" th:data-id="${empresa.id}">
<td>[[${empresa.id}]]</td>
<td> <td>
<a th:href="@{/templates/admin/empresa/{id}(id=${empresa.id})}">[[${empresa.nombre}]]</a> <a th:href="@{/templates/admin/empresa/{id}(id=${empresa.id})}">[[${empresa.nombre}]]</a>
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>[[${empresa.cif}]]</td> <td>[[${empresa.cif}]]</td>
<td>[[${empresa.correo}]]</td> <td>[[${empresa.correo}]]</td>
@ -117,27 +111,81 @@
</div> </div>
</div> </div>
<script src="/orderTable.js"></script> <script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
document.querySelector('#myInput').addEventListener('input', function() { var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/empresa/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/empresa/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "La empresa ha sido eliminada") {
alert("Empresa borrada con exito");
window.location.reload();
} else {
alert("Error al borrar empresa");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value; var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls'); var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount'); var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') { if (query == '') {
// If the search bar is empty, show the pagination controls and the entries count dropdown, and reload the page isSearchBarUsed = false;
paginationControls.style.display = ''; paginationControls.style.display = '';
entriesCountDropdown.style.display = ''; entriesCountDropdown.style.display = '';
table.style.pointerEvents = ''; table.style.pointerEvents = '';
location.reload(); location.reload();
} else { } else {
// If the search bar is not empty, hide the pagination controls and the entries count dropdown, and perform the search isSearchBarUsed = true;
paginationControls.style.display = 'none'; paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none'; entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none'; table.style.pointerEvents = 'none';
@ -149,12 +197,12 @@
tableBody.innerHTML = ''; tableBody.innerHTML = '';
data.forEach(empresa => { data.forEach(empresa => {
var row = document.createElement('tr'); var row = document.createElement('tr');
row.dataset.id = empresa.id;
row.innerHTML = ` row.innerHTML = `
<td>${empresa.id}</td>
<td> <td>
<a href="/templates/admin/empresa/${empresa.id}">${empresa.nombre}</a> ${empresa.nombre}
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>${empresa.cif}</td> <td>${empresa.cif}</td>
<td>${empresa.correo}</td> <td>${empresa.correo}</td>
@ -164,72 +212,54 @@
`; `;
tableBody.appendChild(row); tableBody.appendChild(row);
}); });
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
}); });
} document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
}); });
document.getElementById('create-icon').addEventListener('click', function() { table.style.pointerEvents = 'auto';
window.location = "/admin/empresa/create"; });
}
}); });
document.querySelector('#table').addEventListener('click', function(event) { document.querySelector('#table').addEventListener('click', function(event) {
//When you have a dynamic table to confirm an icon in a row you need to use event.target.matches('') if (event.target.matches('.edit-icon')) {
//And don forget to use # to specify that is an id handleEdit(event);
// or a . to specify that is a class } else if (event.target.matches('.delete-icon')) {
if (event.target.matches('#edit-icon')) { handleDelete(event);
// Handle edit button click
//This gets the ID of the row by getting the first element of the row by using the closest method
//And then getting the text content of the first element
//event. is the event that was triggered
//target. is the element that was clicked
// closest('tr') is the closest tr element to the clicked element
// firstElementChild is the first element of the tr element and .textContent is the text content of the element
const rowId = event.target.closest('tr').firstElementChild.textContent;
<!--console.log('Edit button clicked for row with ID:', rowId);-->
window.location = "/admin/empresa/update/" + rowId;
} else if (event.target.matches('#delete-icon')) {
const rowId = event.target.closest('tr').firstElementChild.textContent;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
} }
});
deleteSpan.onclick = function() { const observer = new MutationObserver(function() {
// Your code here document.querySelectorAll('.edit-icon').forEach(function(icon) {
<!--console.log("Delete button clicked for row with ID: ", rowId)--> icon.addEventListener('click', handleEdit);
$.ajax({
url: '/empresa/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response==="La empresa ha sido eliminado") {
alert("Empresa borrada con exito");
window.location.reload();
}else{
alert("Error al borrar la empresa");
}
}
}); });
} document.querySelectorAll('.delete-icon').forEach(function(icon) {
window.onclick = function(event) { icon.addEventListener('click', handleDelete);
if (event.target === modal) {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
}
}
}); });
});
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/empresa/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script> </script>
</body> </body>
</html> </html>

@ -3,40 +3,234 @@
<head> <head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}"> <link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Title</title> <title>Lista:Familia</title>
<style> <style>
</style> </style>
</head> </head>
<body> <body>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <div class="header">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script> <button onclick="goBack()">Atras</button>
<h1>Familias<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1> <h1>Listado de Familias</h1>
<div class="table"> <a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a>
<table class ="table table-hover table-responsive-xl"> </div>
<input type="text" id="myInput" placeholder="Buscar por...."> <i class="fas fa-plus" id="create-icon"></i>
<div class="table-container">
<table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th>Id</th> <th class="table-header">
<th>Nombre</th> <a th:href="@{'/buscador/familias/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
</tr> Nombre
</a>
</th>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="familia :${familias}"> <tr class="cell" th:each="familia :${items}" th:data-id="${familia.id}">
<td>[[${familia.id}]]</td>
<td><a th:href="@{/templates/admin/familia/{id}(id=${familia.id})}">[[${familia.nombre}]]</a></td>
<td>
[[${familia.nombre}]]
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<button onclick="goBack()">Atras</button> <div class="page">
<nav aria-label="Page navigation" id="paginationControls">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/familia/page/' + ${1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Prim</a>
</li>
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/familia/page/' + ${currentPage - 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ant</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(1, totalPages)}" th:classappend="${pageNum eq currentPage ? 'active' : ''}">
<th:block th:if="${pageNum lt 3 or pageNum gt totalPages - 2 or pageNum eq currentPage - 2 or pageNum eq currentPage - 1 or pageNum eq currentPage or pageNum eq currentPage + 1 or pageNum eq currentPage + 2}">
<a class="page-link" th:href="@{'/buscador/familia/page/' + ${pageNum} + '?query=' + ${query} + '&size=' + ${currentSize}}">[[${pageNum}]]</a>
</th:block>
<th:block th:if="${pageNum eq 3 and currentPage gt 5}">...</th:block>
<th:block th:if="${pageNum eq totalPages - 2 and currentPage lt totalPages - 4}">...</th:block>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/familia/page/' + ${currentPage + 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Sig</a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/familia/page/' + ${totalPages} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ult</a>
</li>
</ul>
</nav>
</div>
<select id="entriesCount">
<option th:each="item : ${itemsPage}" th:value="${item}" th:text="${item}" th:selected="${item == currentSize}"></option>
</select>
<div id="modalDelete" class ="modal">
<div class="modal-content">
<p>¿Estas seguro que quires borar este elemnto?</p>
<span class="delete">Borar</span>
<span class="close">Cancelar</span>
</div>
</div>
<script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/familia/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/familia/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "La familia ha sido eliminada") {
alert("Familia borrada con exito");
window.location.reload();
} else {
alert("Error al borrar familia");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = '';
entriesCountDropdown.style.display = '';
table.style.pointerEvents = '';
location.reload();
} else {
isSearchBarUsed = true;
paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none';
fetch('/buscador/familias/search?query=' + query)
.then(response => response.json())
.then(data => {
var tableBody = document.querySelector('#table tbody');
tableBody.innerHTML = '';
data.forEach(familia => {
var row = document.createElement('tr');
row.dataset.id = familia.id;
row.innerHTML = `
<td>
${familia.nombre}
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
`;
tableBody.appendChild(row);
});
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
});
table.style.pointerEvents = 'auto';
});
}
});
document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
// Create a new observer
const observer = new MutationObserver(function() {
// Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/familia/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script> </script>
</body> </body>
</html> </html>

@ -3,43 +3,272 @@
<head> <head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}"> <link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Title</title> <title>Lista Ofertas</title>
<style> <style>
</style> </style>
</head> </head>
<body> <body>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <div class="header">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script> <button onclick="goBack()">Atras</button>
<h1>Listado de Ofertas<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1> <h1>Listado de Ofertas</h1>
<div class="table"> <a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a>
<table class ="table table-hover table-responsive-xl"> </div>
<input type="text" id="myInput" placeholder="Buscar por...."> <i class="fas fa-plus" id="create-icon"></i>
<div class="scrollable-table">
<table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th>Id</th> <th class="table-header">
<th>Nombre</th> <a th:href="@{'/buscador/ofertas/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
<th>Descripcion</th> Nombre
<th>Fecha</th> </a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ofertas/page/' + ${currentPage} + '?sortField=fecha&sortDir=' + ${reverseSortDir}}">
Fecha
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ofertas/page/' + ${currentPage} + '?sortField=descripcion&sortDir=' + ${reverseSortDir}}">
Descripcion
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ofertas/page/' + ${currentPage} + '?sortField=sucursal.nombre&sortDir=' + ${reverseSortDir}}">
Sucursal
</a>
</th>
<th class="table-header">
<a th:href="@{'/buscador/ofertas/page/' + ${currentPage} + '?sortField=ciclo.nombre&sortDir=' + ${reverseSortDir}}">
Ciclo
</a>
</th>
<th class="table-header">
Skills
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="oferta :${ofertas}"> <tr class="cell" th:each="oferta :${items}" th:data-id="${oferta.id}">
<td>[[${oferta.id}]]</td> <td>[[${oferta.id}]]</td>
<td>[[${oferta.nombre}]]</td> <td>
<td>[[${oferta.descripcion}]]</td> [[${oferta.nombre}]]
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>[[${oferta.fecha}]]</td> <td>[[${oferta.fecha}]]</td>
<td>[[${oferta.descripcion}]]</td>
<td>[[${oferta.sucursal.nombre}]]</td>
<td>[[${oferta.ciclo.nombre}]]</td>
<td>
<span th:each="skill : ${oferta.skills}" th:text="${skill.nombre} + ' '"></span>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<button onclick="goBack()">Atras</button> <div class="page">
<nav aria-label="Page navigation" id="paginationControls">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ofertas/page/' + ${1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Prim</a>
</li>
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ofertas/page/' + ${currentPage - 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ant</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(1, totalPages)}" th:classappend="${pageNum eq currentPage ? 'active' : ''}">
<th:block th:if="${pageNum lt 3 or pageNum gt totalPages - 2 or pageNum eq currentPage - 2 or pageNum eq currentPage - 1 or pageNum eq currentPage or pageNum eq currentPage + 1 or pageNum eq currentPage + 2}">
<a class="page-link" th:href="@{'/buscador/ofertas/page/' + ${pageNum} + '?query=' + ${query} + '&size=' + ${currentSize}}">[[${pageNum}]]</a>
</th:block>
<th:block th:if="${pageNum eq 3 and currentPage gt 5}">...</th:block>
<th:block th:if="${pageNum eq totalPages - 2 and currentPage lt totalPages - 4}">...</th:block>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ofertas/page/' + ${currentPage + 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Sig</a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/ofertas/page/' + ${totalPages} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ult</a>
</li>
</ul>
</nav>
</div>
<select id="entriesCount">
<option th:each="item : ${itemsPage}" th:value="${item}" th:text="${item}" th:selected="${item == currentSize}"></option>
</select>
<div id="modalDelete" class ="modal">
<div class="modal-content">
<p>¿Estas seguro que quires borar este elemnto?</p>
<span class="delete">Borar</span>
<span class="close">Cancelar</span>
</div>
</div>
<script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/oferta/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/oferta/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "La oferta ha sido eliminada") {
alert("Oferta borrada con exito");
window.location.reload();
} else {
alert("Error al borrar oferta");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = '';
entriesCountDropdown.style.display = '';
table.style.pointerEvents = '';
location.reload();
} else {
isSearchBarUsed = true;
paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none';
fetch('/buscador/ofertas/search?query=' + query)
.then(response => response.json())
.then(data => {
var tableBody = document.querySelector('#table tbody');
tableBody.innerHTML = '';
data.forEach(oferta => {
var row = document.createElement('tr');
row.dataset.id = oferta.id;
row.innerHTML = `
<td>
${oferta.nombre}
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
<td>${oferta.fecha}</td>
<td>${oferta.descripcion}</td>
<td>${oferta.sucursal.nombre}</td>
<td>${oferta.ciclo.nombre}</td>
<td>
${oferta.skills.map(skill => skill.nombre).join(', ')}
</td>
`;
tableBody.appendChild(row);
});
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
});
table.style.pointerEvents = 'auto';
});
}
});
document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
// Create a new observer
const observer = new MutationObserver(function() {
// Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/oferta/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script> </script>
</body> </body>
</html> </html>

@ -25,11 +25,6 @@
<table class="table" id="table"> <table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th class="table-header">
<a th:href="@{'/buscador/sectores/page/' + ${currentPage} + '?sortField=id&sortDir=' + ${reverseSortDir}}">
Id
</a>
</th>
<th class="table-header"> <th class="table-header">
<a th:href="@{'/buscador/sectores/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}"> <a th:href="@{'/buscador/sectores/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
Nombre Nombre
@ -37,12 +32,11 @@
</th> </th>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="sector :${sectores}"> <tr class="cell" th:each="sector :${items}" th:data-id="${sector.id}">
<td>[[${sector.id}]]</td>
<td> <td>
<a th:href="@{/sector/{id}(id=${sector.id})}">[[${sector.nombre}]]</a> [[${sector.nombre}]]
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -89,21 +83,79 @@
<script src="/orderTable.js"></script> <script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
document.querySelector('#myInput').addEventListener('input', function() { var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/sector/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/sector/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "El sector ha sido eliminado") {
alert("Sector borrado con exito");
window.location.reload();
} else {
alert("Error al borrar sector");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value; var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls'); var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount'); var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') { if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = ''; paginationControls.style.display = '';
entriesCountDropdown.style.display = ''; entriesCountDropdown.style.display = '';
table.style.pointerEvents = ''; table.style.pointerEvents = '';
location.reload(); location.reload();
} else { } else {
isSearchBarUsed = true;
paginationControls.style.display = 'none'; paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none'; entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none'; table.style.pointerEvents = 'none';
@ -115,69 +167,69 @@
tableBody.innerHTML = ''; tableBody.innerHTML = '';
data.forEach(sector => { data.forEach(sector => {
var row = document.createElement('tr'); var row = document.createElement('tr');
row.dataset.id = sector.id;
row.innerHTML = ` row.innerHTML = `
<td>${sector.id}</td>
<td> <td>
<a href="/templates/admin/sectores/${sector.id}">${sector.nombre}</a> ${sector.id}
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>${sector.nombre}</td>
`; `;
tableBody.appendChild(row); tableBody.appendChild(row);
}); });
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
}); });
} document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
}); });
document.getElementById('create-icon').addEventListener('click', function() { table.style.pointerEvents = 'auto';
console.log("Create button clicked : TEST");
window.location = "/admin/sector/create";
}); });
<!-- EDIT AND UPDATE --> }
});
document.querySelector('#table').addEventListener('click', function(event) { document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
if (event.target.matches('#edit-icon')) { // Create a new observer
const rowId = event.target.closest('tr').firstElementChild.textContent; const observer = new MutationObserver(function() {
window.location = "/admin/sector/update/" + rowId; // Attach the event listeners to the edit and delete icons
} else if (event.target.matches('#delete-icon')) { document.querySelectorAll('.edit-icon').forEach(function(icon) {
const rowId = event.target.closest('tr').firstElementChild.textContent; icon.addEventListener('click', handleEdit);
var modal = document.getElementById("modalDelete"); });
var closeSpan = document.getElementsByClassName("close")[0]; document.querySelectorAll('.delete-icon').forEach(function(icon) {
var deleteSpan = document.getElementsByClassName("delete")[0]; icon.addEventListener('click', handleDelete);
});
});
modal.style.display = "block"; // Start observing the document with the configured parameters
document.body.style.pointerEvents = 'none'; observer.observe(document.querySelector('#table tbody'), { childList: true });
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() { document.getElementById('create-icon').addEventListener('click', function() {
modal.style.display = "none"; console.log("Create button clicked : TEST");
document.body.style.pointerEvents = 'auto'; window.location = "/admin/sector/create";
} });
deleteSpan.onclick = function() { var tableHeaders = document.querySelectorAll('.table-header');
// Your code here tableHeaders.forEach(function(header) {
<!--console.log("Delete button clicked for row with ID: ", rowId)--> header.addEventListener('click', function(event) {
$.ajax({ // If the search bar is currently being used, prevent the default action of the click event
url: '/sector/delete/' + rowId, if (isSearchBarUsed) {
type: 'GET', event.preventDefault();
success: function(response) {
if (response==="El sector ha sido eliminado") {
alert("Empresa borrada con exito");
window.location.reload();
}else{
alert("Error al borrar el sector");
}
} }
}); });
}
window.onclick = function(event) {
if (event.target === modal) {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
}
}
}); });
</script> </script>
</body> </body>

@ -3,39 +3,233 @@
<head> <head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}"> <link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Title</title> <title>Lista: Skills</title>
<style> <style>
</style> </style>
</head> </head>
<body> <body>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <div class="header">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script> <button onclick="goBack()">Atras</button>
<h1>Listado de Skills<a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a></h1> <h1>Listado de Skills</h1>
<div class="table"> <a href="/logout" class="logout-button"><i class="fas fa-door-open"></i></a>
<table class ="table table-hover table-responsive-xl"> </div>
<input type="text" id="myInput" placeholder="Buscar por...."> <i class="fas fa-plus" id="create-icon"></i>
<div class="table-container">
<table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th>Id</th> <th class="table-header">
<th>Nombre</th> <a th:href="@{'/buscador/skills/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
</tr> Nombre
</a>
</th>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="skill :${skills}"> <tr class="cell" th:each="skill :${items}" th:data-id="${skill.id}">
<td>[[${skill.id}]]</td> <td>
<td>[[${skill.nombre}]]</td> [[${skill.nombre}]]
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<button onclick="goBack()">Atras</button> <div class="page">
<nav aria-label="Page navigation" id="paginationControls">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/skills/page/' + ${1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Prim</a>
</li>
<li class="page-item" th:classappend="${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/skills/page/' + ${currentPage - 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ant</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(1, totalPages)}" th:classappend="${pageNum eq currentPage ? 'active' : ''}">
<th:block th:if="${pageNum lt 3 or pageNum gt totalPages - 2 or pageNum eq currentPage - 2 or pageNum eq currentPage - 1 or pageNum eq currentPage or pageNum eq currentPage + 1 or pageNum eq currentPage + 2}">
<a class="page-link" th:href="@{'/buscador/skills/page/' + ${pageNum} + '?query=' + ${query} + '&size=' + ${currentSize}}">[[${pageNum}]]</a>
</th:block>
<th:block th:if="${pageNum eq 3 and currentPage gt 5}">...</th:block>
<th:block th:if="${pageNum eq totalPages - 2 and currentPage lt totalPages - 4}">...</th:block>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/skills/page/' + ${currentPage + 1} + '?query=' + ${query} + '&size=' + ${currentSize}}">Sig</a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link" th:href="@{'/buscador/skills/page/' + ${totalPages} + '?query=' + ${query} + '&size=' + ${currentSize}}">Ult</a>
</li>
</ul>
</nav>
</div>
<select id="entriesCount">
<option th:each="item : ${itemsPage}" th:value="${item}" th:text="${item}" th:selected="${item == currentSize}"></option>
</select>
<div id="modalDelete" class ="modal">
<div class="modal-content">
<p>¿Estas seguro que quires borar este elemnto?</p>
<span class="delete">Borar</span>
<span class="close">Cancelar</span>
</div>
</div>
<script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/skill/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/skill/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "Skill ha sido eliminada") {
alert("Skill borrado con exito");
window.location.reload();
} else {
alert("Error al borrar skill");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = '';
entriesCountDropdown.style.display = '';
table.style.pointerEvents = '';
location.reload();
} else {
isSearchBarUsed = true;
paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none';
fetch('/buscador/skills/search?query=' + query)
.then(response => response.json())
.then(data => {
var tableBody = document.querySelector('#table tbody');
tableBody.innerHTML = '';
data.forEach(skill => {
var row = document.createElement('tr');
row.dataset.id = skill.id;
row.innerHTML = `
<td>
${skill.nombre}
<i class="edit-icon fas fa-pen-square"></i>
<i class="delete-icon fas fa-ban"></i>
</td>
`;
tableBody.appendChild(row);
});
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
});
table.style.pointerEvents = 'auto';
});
}
});
document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('.edit-icon')) {
handleEdit(event);
} else if (event.target.matches('.delete-icon')) {
handleDelete(event);
}
});
// Create a new observer
const observer = new MutationObserver(function() {
// Attach the event listeners to the edit and delete icons
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.addEventListener('click', handleEdit);
});
document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.addEventListener('click', handleDelete);
});
});
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/skill/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script> </script>
</body> </body>
</html> </html>

@ -25,11 +25,6 @@
<table class="table" id="table"> <table class="table" id="table">
<thead class="thread-light"> <thead class="thread-light">
<tr> <tr>
<th class="table-header">
<a th:href="@{'/buscador/sucursales/page/' + ${currentPage} + '?sortField=id&sortDir=' + ${reverseSortDir}}">
Id
</a>
</th>
<th class="table-header"> <th class="table-header">
<a th:href="@{'/buscador/sucursales/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}"> <a th:href="@{'/buscador/sucursales/page/' + ${currentPage} + '?sortField=nombre&sortDir=' + ${reverseSortDir}}">
Nombre Nombre
@ -58,12 +53,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="cell" th:each="sucursal :${sucursales}"> <tr class="cell" th:each="sucursal :${items}" th:data-id="${sucursal.id}">
<td>[[${sucursal.id}]]</td>
<td> <td>
[[${sucursal.nombre}]] [[${sucursal.nombre}]]
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>[[${sucursal.localidad}]]</td> <td>[[${sucursal.localidad}]]</td>
<td>[[${sucursal.direccion}]]</td> <td>[[${sucursal.direccion}]]</td>
@ -114,22 +108,79 @@
<script src="/orderTable.js"></script> <script src="/orderTable.js"></script>
<script> <script>
function goBack() { function goBack() {
window.history.back(); window.history.back();
} }
document.querySelector('#myInput').addEventListener('input', function() { var $table = $('#table');
var $modalDelete = $('#modalDelete');
var $myInput = $('#myInput');
var $createIcon = $('#create-icon');
var isSearchBarUsed = false;
$table.on('click', '.edit-icon', function(event) {
console.log("Edit icon clicked");
handleEdit(event);
});
$table.on('click', '.delete-icon', function(event) {
console.log("Delete icon clicked");
handleDelete(event);
});
function handleEdit(event) {
console.log("handleEdit function called");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
console.log("Row ID: " + rowId);
window.location = "/admin/sucursal/update/" + rowId;
}
function handleDelete(event) {
console.log("handleDelete function called");
console.log("Delete icon clicked");
const row = event.target.closest('tr');
const rowId = row.dataset.id;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
deleteSpan.onclick = function() {
$.ajax({
url: '/sucursal/delete/' + rowId,
type: 'GET',
success: function(response) {
if (response === "La sucursal ha sido eliminada") {
alert("Sucursal borrada con exito");
window.location.reload();
} else {
alert("Error al borrar sucursal");
}
}
});
}
}
$myInput.on('input', function() {
var query = document.querySelector('#myInput').value; var query = document.querySelector('#myInput').value;
var paginationControls = document.querySelector('#paginationControls'); var paginationControls = document.querySelector('#paginationControls');
var entriesCountDropdown = document.querySelector('#entriesCount'); var entriesCountDropdown = document.querySelector('#entriesCount');
if (query == '') { if (query == '') {
isSearchBarUsed = false;
paginationControls.style.display = ''; paginationControls.style.display = '';
entriesCountDropdown.style.display = ''; entriesCountDropdown.style.display = '';
table.style.pointerEvents = ''; table.style.pointerEvents = '';
location.reload(); location.reload();
} else { } else {
isSearchBarUsed = true;
paginationControls.style.display = 'none'; paginationControls.style.display = 'none';
entriesCountDropdown.style.display = 'none'; entriesCountDropdown.style.display = 'none';
table.style.pointerEvents = 'none'; table.style.pointerEvents = 'none';
@ -141,75 +192,73 @@
tableBody.innerHTML = ''; tableBody.innerHTML = '';
data.forEach(sucursal => { data.forEach(sucursal => {
var row = document.createElement('tr'); var row = document.createElement('tr');
row.dataset.id = sucursal.id;
row.innerHTML = ` row.innerHTML = `
<td>${sucursal.id}</td>
<td> <td>
${sucursal.nombre} ${sucursal.nombre}
<i id="edit-icon" class="fas fa-pen-square"></i> <i class="edit-icon fas fa-pen-square"></i>
<i id="delete-icon" class="fas fa-ban"></i> <i class="delete-icon fas fa-ban"></i>
</td> </td>
<td>${sucursal.localidad}</td> <td>${sucursal.localidad}</td>
<td>${sucursal.direccion}</td> <td>${sucursal.direccion}</td>
<td>${sucursal.sedeCentral}</td> <td>${sucursal.sedeCentral}</td>
<td>${sucursal.empresa.nombre}</td> <td>${sucursal.empresa.nombre}</td>
`; `;
tableBody.appendChild(row); tableBody.appendChild(row);
}); });
document.querySelectorAll('.edit-icon').forEach(function(icon) {
icon.removeEventListener('click', handleEdit);
icon.addEventListener('click', handleEdit);
console.log("Edit icon event listener attached");
}); });
} document.querySelectorAll('.delete-icon').forEach(function(icon) {
icon.removeEventListener('click', handleDelete);
icon.addEventListener('click', handleDelete);
console.log("Delete icon event listener attached");
}); });
document.getElementById('create-icon').addEventListener('click', function() { table.style.pointerEvents = 'auto';
window.location = "/admin/sucursal/create"; });
}
}); });
document.querySelector('#table').addEventListener('click', function(event) { document.querySelector('#table').addEventListener('click', function(event) {
if (event.target.matches('#edit-icon')) { if (event.target.matches('.edit-icon')) {
const rowId = event.target.closest('tr').firstElementChild.textContent; handleEdit(event);
window.location = "/admin/sucursal/update/" + rowId; } else if (event.target.matches('.delete-icon')) {
} else if (event.target.matches('#delete-icon')) { handleDelete(event);
const rowId = event.target.closest('tr').firstElementChild.textContent;
var modal = document.getElementById("modalDelete");
var closeSpan = document.getElementsByClassName("close")[0];
var deleteSpan = document.getElementsByClassName("delete")[0];
modal.style.display = "block";
document.body.style.pointerEvents = 'none';
modal.style.pointerEvents = 'auto';
closeSpan.onclick = function() {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
} }
});
deleteSpan.onclick = function() { // Create a new observer
// Your code here const observer = new MutationObserver(function() {
<!--console.log("Delete button clicked for row with ID: ", rowId)--> // Attach the event listeners to the edit and delete icons
$.ajax({ document.querySelectorAll('.edit-icon').forEach(function(icon) {
url: '/sucursal/delete/' + rowId, icon.addEventListener('click', handleEdit);
type: 'GET', });
success: function(response) { document.querySelectorAll('.delete-icon').forEach(function(icon) {
if (response==="La empresa ha sido eliminado") { icon.addEventListener('click', handleDelete);
alert("Empresa borrada con exito");
window.location.reload();
}else{
alert("Error al borrar la empresa");
}
}
}); });
}
window.onclick = function(event) {
if (event.target === modal) {
modal.style.display = "none";
document.body.style.pointerEvents = 'auto';
}
}
}
}); });
// Start observing the document with the configured parameters
observer.observe(document.querySelector('#table tbody'), { childList: true });
document.getElementById('create-icon').addEventListener('click', function() {
console.log("Create button clicked : TEST");
window.location = "/admin/sucursal/create";
});
var tableHeaders = document.querySelectorAll('.table-header');
tableHeaders.forEach(function(header) {
header.addEventListener('click', function(event) {
// If the search bar is currently being used, prevent the default action of the click event
if (isSearchBarUsed) {
event.preventDefault();
}
});
});
</script> </script>
</body> </body>
</html> </html>
Loading…
Cancel
Save

Powered by INFORMATICA.FP.EDU.ES.